¿Cómo puedo analizar las fechas y convertir las zonas horarias en Perl?

He usado la función localtime en Perl para obtener la fecha y la hora actuales, pero necesito analizar las fechas existentes. Tengo una fecha GMT en el siguiente formato: “20090103 12:00” Me gustaría analizarlo en un objeto de fecha con el que puedo trabajar y luego convertir la hora / fecha GMT en mi zona horaria actual, que actualmente es hora estándar del este . Así que me gustaría convertir “20090103 12:00” a “20090103 7:00”. Cualquier información sobre cómo hacer esto sería muy apreciada.

Debido a que las interfaces de manejo de fechas integradas de Perl son un poco torpes y usted termina pasando alrededor de media docena de variables, la mejor manera es usar DateTime o Time :: Piece . DateTime es el objeto de fecha Perl que canta y baila, y es probable que quieras usarlo, pero Time :: Piece es más simple y perfectamente adecuado para esta tarea, tiene la ventaja de enviarlo con 5.10 y la técnica es básicamente lo mismo para ambos.

Esta es la manera simple y flexible de utilizar Time :: Piece y strptime .

#!/usr/bin/perl use 5.10.0; use strict; use warnings; use Time::Piece; # Read the date from the command line. my $date = shift; # Parse the date using strptime(), which uses strftime() formats. my $time = Time::Piece->strptime($date, "%Y%m%d %H:%M"); # Here it is, parsed but still in GMT. say $time->datetime; # Create a localtime object for the same timestamp. $time = localtime($time->epoch); # And here it is localized. say $time->datetime; 

Y aquí está el camino a mano, por contraste.

Dado que el formato es fijo, una expresión regular funcionará bien, pero si el formato cambia, deberá ajustar la expresión regular.

 my($year, $mon, $day, $hour, $min) = $date =~ /^(\d{4}) (\d{2}) (\d{2})\ (\d{2}):(\d{2})$/x; 

Luego conviértalo en tiempo de época Unix (segundos desde el 1 de enero de 1970)

 use Time::Local; # Note that all the internal Perl date handling functions take month # from 0 and the year starting at 1900. Blame C (or blame Larry for # parroting C). my $time = timegm(0, $min, $hour, $day, $mon - 1, $year - 1900); 

Y luego de vuelta a tu hora local.

 (undef, $min, $hour, $day, $mon, $year) = localtime($time); my $local_date = sprintf "%d%02d%02d %02d:%02d\n", $year + 1900, $mon + 1, $day, $hour, $min; 

Aquí hay un ejemplo, usando DateTime y su módulo de formato strptime .

 use DateTime; use DateTime::Format::Strptime; my $val = "20090103 12:00"; my $format = new DateTime::Format::Strptime( pattern => '%Y%m%d %H:%M', time_zone => 'GMT', ); my $date = $format->parse_datetime($val); print $date->strftime("%Y%m%d %H:%M %Z")."\n"; $date->set_time_zone("America/New_York"); # or "local" print $date->strftime("%Y%m%d %H:%M %Z")."\n"; $ perl dates.pl 20090103 12:00 UTC 20090103 07:00 EST 

Si quisieras analizar el tiempo local, así es como lo harías 🙂

 use DateTime; my @time = (localtime); my $date = DateTime->new(year => $time[5]+1900, month => $time[4]+1, day => $time[3], hour => $time[2], minute => $time[1], second => $time[0], time_zone => "America/New_York"); print $date->strftime("%F %r %Z")."\n"; $date->set_time_zone("Europe/Prague"); print $date->strftime("%F %r %Z")."\n"; 

Eso es lo que haría …

 #!/usr/bin/perl use Date::Parse; use POSIX; $orig = "20090103 12:00"; print strftime("%Y%m%d %R", localtime(str2time($orig, 'GMT'))); 

También puede usar Time::ParseDate y parsedate() lugar de Date::Parse y str2time() . Tenga en cuenta que la atmósfera estándar de facto. parece ser DateTime (pero es posible que no desee utilizar la syntax OO solo para convertir una marca de tiempo).

Elige tu opción:

  • DateTime :: * (alternativamente, en datetime.perl.org )
  • Fecha :: Manip
  • Fecha :: Calc (última actualización en 2004)

Hay un trillón de otros, sin duda, pero probablemente sean los principales contendientes.

 use strict; use warnings; my ($sec,$min,$hour,$day,$month,$year)=localtime(); $year+=1900; $month+=1; $today_time = sprintf("%02d-%02d-%04d %02d:%02d:%02d",$day,$month,$year,$hour,$min,$sec); print $today_time;