2016-03-13 2 views
0

По какой-то причине следующий сценарий, который я использую для вычисления разницы во времени двух заданных дат/времени, отключен на час. Не уверен, связано ли это с летним временем. Кто-нибудь знает почему?Расчет разницы во времени Perl Script отключен на один час

Если возможно, я хотел бы знать, как добавить миллисекунды в расчет.

#!/usr/bin/perl 

use strict; 
use warnings; 

use Time::Local; 

sub str2epoch { 
    my $str = shift; 
    my ($date, $time) = split(/\s+/, $str); 
    my ($yr, $mon, $dd) = split(/\-/, $date); 
    my ($hr, $min, $sec) = split(/:/, $time); 
    $yr -= 1900; 
    $mon -= 1; 

    $hr -= 24 if ($hr == 24); 

    if ($sec =~ m/PM/ && $hr < 12){ 
      $hr += 12; 
      $sec =~ s/PM//; 
    } elsif ($sec =~ m/PM/ && $hr == 12) { 
      $sec =~ s/PM//; 
    } 

    if ($sec =~ m/AM/ && $hr == 12) { 
      $hr -= 12; 
    } elsif ($sec =~ m/AM/ && $hr < 12) { 
      $sec =~ s/AM//; 
    } 

    return timelocal($sec,$min,$hr,$dd,$mon,$yr); 
} 

{ 
    my $str1 = "2016-03-12 06:31:55"; 
    my $str2 = "2016-03-13 06:31:55"; 

    my $t1 = str2epoch($str1); 
    my $t2 = str2epoch($str2); 
    my $diff = $t2 - $t1; 
    my $hrss = $diff/3600/24; 
    my $hr_diff = int ($diff/3600); 
    my $r = $diff%3600; 
    #my $milli = $diff/3600/24/60/60/60; 
    my $min = 0; 
    my $sec = 0; 
    #my $milli = 0; 

    if ($r > 60) { 
     $min = int($r/60); 
     $sec = $r%60; 
    } else { 
     $sec = $r; 
    } 

    print "$str1 to $str2: $hr_diff hrs, $min min, $sec sec, millisecond\n"; 
} 

Выход должен быть: 24 часа. 0 мин, 0 сек. Но из-за перехода на летнее время он выводит: 23 часа. 0 мин 0 сек

ответ

3

Я не знаю, почему вы утверждаете, что выход должен быть 24 часа. Как вы намекали, вы живете где-то, что переключилось на летнее время во время этого промежутка, так что между двумя указанными датами было всего 23 часа. Выход правильный.

Я думаю, что вы пытаетесь найти разницу между двумя датами - днями, часами и т. Д., Но вы не осознали, что тот факт, что не все дни имеют 24 часа (и это не все минуты имеют 60 секунд) препятствует вам делать это с нескольких секунд.

Для этого я бы использовал модуль DateTime.

use strict; 
use warnings; 

use DateTime::Format::Strptime  qw(); 
use DateTime::Format::Human::Duration qw(); 

my $dt_format = DateTime::Format::Strptime->new(
    pattern => '%Y-%m-%d %H:%M:%S', 
    time_zone => 'local', 
    on_error => 'croak', 
); 

my $dur_format = DateTime::Format::Human::Duration->new(); 

my $dt1 = $dt_format->parse_datetime("2016-03-12 06:31:55"); 
my $dt2 = $dt_format->parse_datetime("2016-03-13 06:31:55"); 
my $dur = $dt1->delta_md($dt2); 
print($dur_format->format_duration($dur), "\n"); # 1 day 
+0

Для этого требуется модуль DateTime. Я получаю эту ошибку: Невозможно найти DateTime/Format/Strptime.pm в @INC (вам может потребоваться установить модуль DateTime :: Format :: Strptime) (@INC содержит:/usr/lib/perl5/site_perl/5.22/i686-cygwin-threads-64int /usr/lib/perl5/site_perl/5.22 /usr/lib/perl5/vendor_perl/5.22/i686-cygwin-threads-64int /usr/lib/perl5/vendor_perl/5.22/usr/lib/perl5/5.22/i686-cygwin-threads-64int /usr/lib/perl5/5.22.) в строке findtime2.pl 6. BEGIN failed - компиляция прервана в строке findtime2.pl 6. Есть ли способ установить модуль через Cygwin? – SumoStash

+0

Легко: 'cpan DateTime :: Format :: Strptime' – ikegami

Смежные вопросы