in reply to Elapsed date and time

Ok I spent way too much time on this, but I couldn't sleep without figuring this out. It needs to be patched to use BigInt so that it can deal with time lengths over I think 300 days or so, but it tests right, so here it is.. This could probably be cleaned up some as well, but like I said its 4am localtime, and I just couldnt sleep without resolving this...
# Assume the following values $start = 'Dec 1 2003 4 00:00 AM'; $end = 'Jan 2 2004 5 00:00 AM'; ($s_seconds, $s_year) = parse($start); ($e_seconds, $e_year) = parse($end); if ($s_seconds < $e_seconds) { $elapsed = $e_seconds - $s_seconds; } else { # # we must have rolled over to a new year so... # Grab the remaining seconds in the old year + the seconds in the new +year # $elapsed = $e_seconds + ( $s_year - $s_seconds ); } $days = (split(/\./, $elapsed / 86400))[0]; $rem = $elapsed - (86400 * $days); $hours = (split(/\./, $rem / 3600))[0]; $rem -= 3600 * $hours; $mins = (split(/\./, $rem / 60))[0]; $seconds = $rem - ($mins * 60); print "Total time was: $days Days $hours Hrs $mins Mins $seconds Secs\ +n"; sub parse { my($line) = shift; my($mth,$day,$year,$hour,$tosplit,$arg) = split(/\s+/, $line); my($min, $sec) = split(/:/, $tosplit); # Add 12 if we are in the PM if ($arg =~ /PM/) { $hour += 12; # Set hour to 0 if its 12 AM } elsif ($hour == 12) { $hour = 0; } my($base, $total) = this_year($mth, $year); # beginning of the month + base == # of secs since beginning of year my($return) = $base + $sec + ($min * 60) + ($hour * 3600) + ($day * + 86400); return($return, $total); } sub this_year { my($mth,$year,$thirty,$thirtyo,$tofind,$base,$total, %months); ($mth, $year) = @_; # number of seconds in a month with thirty days and thirty one days $thirty = "2592000"; $thirtyo = "2678400"; %months = ( Jan => [1, $thirtyo ], Feb => [2, '2419200'], Mar => [3, $thirty +o], Apr => [4, $thirty ], May => [5, $thirtyo ], Jun => [6, $thirty +], Jul => [7, $thirtyo ], Aug => [8, $thirtyo ], Sep => [9, $thirty +], Oct => [10, $thirtyo], Nov => [11, $thirty ], Dec => [12, $thirt +yo] ); # Stupid calendar system :P # Man its way to late to be computing leap years.. stupid stupid syste +m if (($year % 4) == 0) { $months{Feb}->[1] += '86400'; if ( ($year % 100) == 0 && ($year % 400) != 0 ) { $months{Feb}->[1] -= '86400'; } } $tofind = $months{$mth}->[0]; for ( sort { $months{$a}->[0] <=> $months{$b}->[0] } keys %months ) + { $base += $months{$_}->[1] if ($tofind >= $months{$_}->[0]); $total += $months{$_}->[1]; } return($base,$total); }
This prints out
Total time was: 32 Days 1 Hrs 0 Mins 0 Secs


/* And the Creator, against his better judgement, wrote man.c */

Replies are listed 'Best First'.
Re: Re: Elapsed date and time
by hv (Prior) on Mar 04, 2003 at 13:28 UTC
    It needs to be patched to use BigInt so that it can deal with time lengths over I think 300 days or so

    Not sure where you got that from: a 31-bit integer will hold enough seconds for about 68 years, which is why most Unix-oriented code (with the epoch starting at Jan 1, 1970) can only handle dates up to Jan 19, 2038.

    Hugo
      You know what.. you're right... When I was doing testing though, the same algorithm that worked for smaller values got truncated when I tried to compute lengths greater than 1 year. Since it was so early, I just thought I was running out of space in the 'int', and this morning I was thinking about using an array to store the value, but you're right I shouldn't need to.. I'll have to dig in and see if I can figure out whats going on.

      /* And the Creator, against his better judgement, wrote man.c */