Como posso analisar datas e converter fusos horários em Perl?

Usei a function localtime em Perl para obter a data e a hora atuais, mas preciso analisar as datas existentes. Tenho uma data GMT no seguinte formato: “20090103 12:00” Gostaria de analisá-la em um object de data com o qual posso trabalhar e, em seguida, converter a hora / data GMT em meu fuso horário atual que é atualmente o horário padrão do leste . Então eu gostaria de converter “20090103 12:00” para “20090103 7:00” qualquer informação sobre como fazer isso seria muito apreciada.

Como o Perl embutido em interfaces de manipulação de datas é meio desajeitado e você acaba passando cerca de meia dúzia de variables, a melhor maneira é usar DateTime ou Time :: Piece . DateTime é o object de data Perl que canta e dança, e você provavelmente vai querer usá-lo, mas o Time :: Piece é mais simples e perfeitamente adequado para essa tarefa, tem a vantagem de ser enviado com 5.10 e a técnica é basicamente o mesmo para ambos.

Aqui está a maneira simples e flexível usando Time :: Piece e 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; 

E aqui está o caminho da mão, para contraste.

Uma vez que o formato é fixo, uma expressão regular se sairá bem, mas se o formato mudar, você terá que ajustar o regex.

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

Em seguida, converta-o em Unix epoch time (segundos desde 1º de janeiro 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); 

E depois de volta ao seu horário 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; 

Aqui está um exemplo, usando o DateTime e seu 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 

Se você quisesse analisar o horário local, veja como você faria isso 🙂

 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"; 

Isso é o que eu faria …

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

Você também pode usar Time::ParseDate e parsedate() vez de Date::Parse e str2time() . Note que o padrão de fato atm. parece ser DateTime (mas você pode não querer usar a syntax OO apenas para converter um timestamp).

Faça sua escolha:

  • DateTime :: * (alternativamente, em datetime.perl.org )
  • Data :: Manip
  • Data :: Calc (última atualização em 2004)

Há um zilhão de outros, sem dúvida, mas provavelmente são os principais candidatos.

 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;