### DIfference in days hours and second between dates

by *alexandre* (Novice)
 on Jun 13, 2013 at 15:39 UTC Need Help??
*alexandre* has asked for the wisdom of the Perl Monks concerning the following question:

Hi a few years ago I've written a perl function to calculate the difference between two dates in perl.
```sub timeDiff {
local our \$invoke = shift || '';
local our \$date1 = shift || '';
local our \$date2 = shift || '';
#'2005-08-02 0:26:47', date2 =>  '2005-08-03 13:27:46'
local our  @offset_days = qw(0 31 59 90 120 151 181 212 243 273 30
+4 334);

local our \$year1  = substr(\$date1, 0, 4);
local our \$month1 = substr(\$date1, 5, 2);
local our \$day1   = substr(\$date1, 8, 2);
local our \$hh1    = substr(\$date1,11, 2) || 0;
local our \$mm1    = substr(\$date1,14, 2) || 0;
local our \$ss1    = substr(\$date1,17, 2) if (length(\$date1) > 16);
#\$ss1  ||= 0;

local our \$year2  = substr(\$date2, 0, 4);
local our \$month2 = substr(\$date2, 5, 2);
local our \$day2   = substr(\$date2, 8, 2);
local our \$hh2    = substr(\$date2,11, 2) || 0;
local our \$mm2    = substr(\$date2,14, 2) || 0;
local our \$ss2    = substr(\$date2,17, 2) if (length(\$date2) > 16);
#\$ss2  ||= 0;

local our \$total_days1 = \$offset_days[\$month1 - 1] + \$day1 + 365 *
+ \$year1;
local our \$total_days2 = \$offset_days[\$month2 - 1] + \$day2 + 365 *
+ \$year2;
local our \$days_diff   = \$total_days2 - \$total_days1;

local our \$seconds1 = \$total_days1 * 86400 + \$hh1 * 3600 + \$mm1 *
+60 + \$ss1;
local our \$seconds2 = \$total_days2 * 86400 + \$hh2 * 3600 + \$mm2 *
+60 + \$ss2;

local our \$ssDiff = \$seconds2 - \$seconds1;

local our \$dd     = int(\$ssDiff / 86400);
local our \$hh     = int(\$ssDiff /  3600) - \$dd *    24;
local our \$mm     = int(\$ssDiff /    60) - \$dd *  1440 - \$hh *   6
+0;
local our \$ss     = int(\$ssDiff /     1) - \$dd * 86400 - \$hh * 360
+0 - \$mm * 60;

return "\$dd J \$hh H \$mm M \$ss Sec";
}

But the result is not correct anymore it's give the resultat for the difference between today and the 2013-07-03 00:00:00 as the following result 734581 J 6 H 34 M 26 Sec where J is number of days h hours M minutes and sec seconds

Replies are listed 'Best First'.
Re: DIfference in days hours and second between dates
by davido (Archbishop) on Jun 13, 2013 at 15:56 UTC

print timeDiff('', "2013-06-13 0:01:01", "2013-07-03 00:00:00" ), "\n"; gives me the following output:

```19 J 23 H 58 M 59 Sec

Which, while I'm not sure it's 100% accurate, it's far from 734581 days. Have you tried printing the variables you're passing as parameters immediately before calling the function? Could be a case of garbage in.

....*sigh*..... This really ought to be relegated to DateTime, or one of the other CPAN offerings that is well maintained. Date calculations are not as easy as they look. What's with "local our" instead of true "my" variables? ...just curious; I don't see "local our", um, ever.

Dave

I think its because he's showing some old code he wrote, not new code. I mentioned the "local our" oddity in an earlier question of his on Re: perl variable displayed as a hash value.

If you spot any bugs in my solutions, it's because I've deliberately left them in as an exercise for the reader! :-)

Yeah, I understand that it's old code. But "our" was introduced when, Perl 5.8 maybe? And "my" pretty much came with Perl 5. So where did the idiom come from? What book, what website, what teacher is promoting it? The idea came from somewhere, or a misinterpretation of an idea that came from somewhere. ;)

It would never have been considered a "best practice" for variables that need to be lexically scoped to a subroutine in any version of Perl since Perl 5.

Dave

Re: DIfference in days hours and second between dates
by space_monk (Chaplain) on Jun 13, 2013 at 15:55 UTC

Please look at the module DateTime or Date::Calc and replace your code with calls to it.

The following is undebugged and untested, so you're welcome to fix any minor issues that show up. :-)

```use strict;
use warnings;
use DateTime;
use DateTime::Duration;
use DateTime::Format::Strptime;

sub timeDiff {
# invoke isn't used, what's it for?
my \$invoke = shift || '';
my \$date1 = shift || '';
my \$date2 = shift || '';

my \$dParser = DateTime::Format::Strptime->new(
pattern   => '%F %T',
locale    => 'en',
time_zone => 'CET',
on_error  => 'croak',
);

my \$dt1 = \$dParser->parse_datetime(\$date1);
my \$dt2 = \$dParser->parse_datetime(\$date2);

my \$dur = \$dt2 - \$dt1;

my (\$dd, \$hh, \$mm, \$ss) = \$dur->in_units('days', 'hours', 'minutes
+', 'seconds');

return "\$dd J \$hh H \$mm M \$ss Sec";
}
If you spot any bugs in my solutions, it's because I've deliberately left them in as an exercise for the reader! :-)
Re: DIfference in days hours and second between dates
by perlfan (Curate) on Jun 13, 2013 at 16:10 UTC
Oh my - !DIY (from most recent YAPC).
Re: DIfference in days hours and second between dates
by poj (Monsignor) on Jun 13, 2013 at 16:08 UTC
I would check the today parameter, this gives your results
```print timeDiff('','0000-00-13 17:25:34','2013-07-03 00:00:00');
poj

Create A New User
Node Status?
node history
Node Type: perlquestion [id://1038778]
Approved by davido
help
Chatterbox?
 [karlgoethebier]: before i forget it: good morning

How do I use this? | Other CB clients
Other Users?
Others wandering the Monastery: (5)
As of 2018-01-20 09:38 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
How did you see in the new year?

Results (226 votes). Check out past polls.

Notices?