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/perluse 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
``````

Top