Pregunta

Dada una fecha/hora como una matriz de (año, mes, día, hora, minuto, segundo), ¿cómo la convertiría a tiempo de época, es decir, la cantidad de segundos desde 1970-01-01 00:00:00 GMT? ?

Pregunta extra:Si se le da la fecha/hora como una cadena, ¿cómo la analizaría primero en la matriz (y,m,d,h,m,s)?

¿Fue útil?

Solución 2

Esta es la forma más sencilla de obtener la hora Unix:

use Time::Local;
timelocal($second,$minute,$hour,$day,$month-1,$year);

Tenga en cuenta el orden inverso de los argumentos y que enero es el mes 0.Para muchas más opciones, consulte el Fecha y hora módulo de CPAN.

En cuanto al análisis, consulte el Fecha::Analizar módulo de CPAN.Si realmente necesita ser sofisticado con el análisis de fechas, el Fecha::Manip puede ser útil, aunque su propia documentación le advierte que no lo utilice, ya que lleva mucho equipaje (sabe cosas como vacaciones de negocios comunes, por ejemplo) y otras soluciones son mucho más rápidas.

Si sabe algo sobre el formato de fecha/hora que analizará, entonces una simple expresión regular puede ser suficiente, pero probablemente sea mejor que utilice un módulo CPAN apropiado.Por ejemplo, si sabe que las fechas siempre estarán en orden YMDHMS, utilice el módulo CPAN FechaHora::Formato::ISO8601.


Para mi propia referencia, al menos, a continuación se muestra una función que uso para una aplicación donde sé que las fechas siempre estarán en orden YMDHMS con toda o parte de la parte "HMS" opcional.Acepta cualquier delimitador (por ejemplo, "2009-02-15" o "2009.02.15").Devuelve la hora Unix correspondiente (segundos desde 1970-01-01 00:00:00 GMT) o -1 si no pudo analizarla (lo que significa que será mejor que se asegure de que nunca necesitará analizar legítimamente la fecha 1969). 12-31 23:59:59).También supone que los años de dos dígitos XX hasta "69" se refieren a "20XX", de lo contrario "19XX" (por ejemplo, "50-02-15" significa 2050-02-15 pero "75-02-15" significa 1975- 02-15).

use Time::Local;

sub parsedate { 
  my($s) = @_;
  my($year, $month, $day, $hour, $minute, $second);

  if($s =~ m{^\s*(\d{1,4})\W*0*(\d{1,2})\W*0*(\d{1,2})\W*0*
                 (\d{0,2})\W*0*(\d{0,2})\W*0*(\d{0,2})}x) {
    $year = $1;  $month = $2;   $day = $3;
    $hour = $4;  $minute = $5;  $second = $6;
    $hour |= 0;  $minute |= 0;  $second |= 0;  # defaults.
    $year = ($year<100 ? ($year<70 ? 2000+$year : 1900+$year) : $year);
    return timelocal($second,$minute,$hour,$day,$month-1,$year);  
  }
  return -1;
}

Otros consejos

Si estás usando el Fecha y hora módulo, puede llamar al época() método en un objeto DateTime, ya que eso es lo que se considera hora Unix.

El uso de DateTimes le permite convertir con bastante facilidad objetos de época a fecha.

Alternativamente, hora local y gmtime convertirá una época en una matriz que contiene día, mes y año, y timelocal y timegm del Hora::Módulo local hará lo contrario, convirtiendo una serie de elementos de tiempo (segundos, minutos, ..., días, meses, etc.) en una época.

Para analizar una fecha, mire Fecha::Analizar en CPAN.

$ENV{TZ}="GMT";
POSIX::tzset();
$time = POSIX::mktime($s,$m,$h,$d,$mo-1,$y-1900);

Sé que esta es una vieja pregunta, pero pensé en ofrecer otra respuesta.

Time::Piece es central a partir de Perl 5.9.5

Esto permite analizar el tiempo en formatos arbitrarios a través del strptime método.

p.ej.:

my $t = Time::Piece->strptime("Sunday 3rd Nov, 1943",
                              "%A %drd %b, %Y");

La parte útil es que, debido a que es un objeto sobrecargado, puedes usarlo para comparaciones numéricas.

p.ej.

if ( $t < time() ) { #do something }

O si accede a él en un contexto de cadena:

print $t,"\n"; 

Usted obtiene:

Wed Nov  3 00:00:00 1943

Hay un montón de métodos de acceso que permiten otras transformaciones útiles basadas en el tiempo. https://metacpan.org/pod/Tiempo::Pieza

Obtener fecha::Manip de CPAN, entonces:

use Date::Manip;
$string = '18-Sep-2008 20:09'; # or a wide range of other date formats
$unix_time = UnixDate( ParseDate($string), "%s" );

editar:

Date::Manip es grande y lento, pero muy flexible en el análisis y es perl puro.Úselo si tiene prisa cuando escribe código y sabe que no tendrá prisa cuando lo ejecute.

p.ej.Úselo para analizar las opciones de la línea de comandos una vez al inicio, pero no lo use para analizar grandes cantidades de datos en un servidor web ocupado.

Ver los comentarios de los autores.

(Gracias al autor del primer comentario a continuación)

Mi analizador de fecha y hora favorito es FechaHora::Formato::ISO8601 Una vez que lo hayas hecho funcionar, tendrás un objeto DateTime, fácilmente convertible a segundos de época con epoch()

Hay muchos módulos de manipulación de fechas en CPAN.Mi favorito particular es Fecha y hora y puedes usar el módulos de tiempo de ejecución para analizar fechas en formatos arbitrarios.También hay muchos módulos DateTime::Format en CPAN para manejar formatos de fecha especializados, pero strptime es el más genérico.

Para mayor referencia, un revestimiento único que se puede aplicar, por ejemplo, !#/bin/sh guiones.

EPOCH="`perl -e 'use Time::Local; print timelocal('${SEC}','${MIN}','${HOUR}','${DAY}','${MONTH}','${YEAR}'),\"\n\";'`"

¡Solo recuerda evitar los valores octales!

Posiblemente uno de los mejores ejemplos de "Hay más de una manera de hacerlo", con o sin la ayuda de CPAN.

Si tiene control sobre lo que se le pasa como "fecha/hora", le sugiero que vaya al Fecha y hora ruta, ya sea usando una subclase específica Date::Time::Format, o usando DateTime::Format::Strptime si no hay ninguna que admita su extravagante formato de fecha (consulte la Preguntas frecuentes sobre fecha y hora para más detalles).En general, Date::Time es el camino a seguir si quieres hacer algo serio con el resultado:Pocas clases de CPAN son tan retentivas anales y tan obsesivamente precisas.

Si esperas cosas raras de forma libre, tíralas a Fecha::Analizar's str2time() método, que le dará un valor de segundos desde la época con el que luego podrá salirse con la suya, sin la sobrecarga de Fecha::Manip.

Un filtro que convierte cualquier fecha en varios formatos relacionados con ISO (y quién usaría cualquier otra cosa después de leer los escritos del Mighty Kuhn?) en la entrada estándar al tiempo de segundos desde la época en la salida estándar podría servir para ilustrar ambas partes:

martind@whitewater:~$ cat `which isoToEpoch`
#!/usr/bin/perl -w
use strict;
use Time::Piece;
# sudo apt-get install libtime-piece-perl
while (<>) {
  # date --iso=s:
  # 2007-02-15T18:25:42-0800
  # Other matched formats:
  # 2007-02-15 13:50:29 (UTC-0800)
  # 2007-02-15 13:50:29 (UTC-08:00)
  s/(\d{4}-\d{2}-\d{2}([T ])\d{2}:\d{2}:\d{2})(?:\.\d+)? ?(?:\(UTC)?([+\-]\d{2})?:?00\)?/Time::Piece->strptime ($1, "%Y-%m-%d$2%H:%M:%S")->epoch - (defined ($3) ? $3 * 3600 : 0)/eg;
  print;
}
martind@whitewater:~$ 

Si solo está buscando una utilidad de línea de comandos (es decir, no algo que pueda ser llamado desde otras funciones), pruebe este script.Se supone la existencia de la fecha GNU (presente en prácticamente cualquier sistema Linux):

#! /usr/bin/perl -w

use strict;

$_ = (join ' ', @ARGV);
$_ ||= <STDIN>;

chomp;

if (/^[\d.]+$/) {
    print scalar localtime $_;
    print "\n";
}
else {
    exec "date -d '$_' +%s";
}

Así es como funciona:

$ Time now
1221763842

$ Time yesterday
1221677444

$ Time 1221677444
Wed Sep 17 11:50:44 2008

$ Time '12:30pm jan 4 1987'
536790600

$ Time '9am 8 weeks ago'
1216915200
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top