当前位置: 动力学知识库 > 问答 > 编程问答 >

datetime - Perl Script time difference calculation is off by one hour

问题描述:

For some reason the following script I use to calculate the time differences of two given date/time is off by an hour. Not sure if it's related to daylight saving. Anyone knows why?

If possible, I would like to know how to add milliseconds to the calculation.

#!/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";

}

The output should be: 24 hrs. 0 min, 0 sec But due to daylight saving, it output: 23 hrs. 0 min, 0 sec

网友答案:

I don't know why you claim the output should be 24 hours. As you hinted, you inhabit somewhere that switched to Daylight Saving Time during that span, so there were only 23 hours between the two date-times in question. The output is correct.

I think you're trying to find the difference between two date-times in terms of days, hours, etc., but you haven't realized that the fact that not all days have 24 hours (and that not all minutes have 60 seconds) prevents you from doing that from a number of seconds.

To do that, I'd use the DateTime module.

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
分享给朋友:
您可能感兴趣的文章:
随机阅读: