Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation

Date difference?

by BUU (Prior)
on Apr 28, 2002 at 22:22 UTC ( #162721=perlquestion: print w/replies, xml ) Need Help??

BUU has asked for the wisdom of the Perl Monks concerning the following question:

What im trying to do, is find the difference between to dates, one in a mysql timestamp format, the other in the localtime format, in the form of seconds:minutes:hours etc. I tried to use Class::Date, but all i could get it to do was give me the number of seconds between the dates, which when i tried to get it to give me a nice string, always gave me something like '1970 january 1..', b/c it adds the seconds onto that date or something like that. None of the other modules on cpan seemed to do what i wanted, they all just appeared to be methods for deterimining a specific date in time. Anyone know of a good module or something? This is the code i came up with:
my ($i,$d,@posttime,@difference,@t); my $posttime=shift; my @mytime=(localtime)[0..5]; $mytime[5]+=1900; $mytime[4]+=1; for(my $i=0;$i<scalar @t;$i++){next if $i==0;$mytime[$i]=(length $ +mytime[$i]==1)?'0'.$mytime[$i]:$mytime[$i]}; unshift @posttime,(substr "$posttime",0,4); for($i=4;$i<14;$i+=2){unshift @posttime,(substr "$posttime",$i,2); +} if(($mytime[0]-$posttime[0])<0){$mytime[1]--;$mytime[0]+=60;} $difference[0]=($mytime[0]-$posttime[0]); if(($mytime[1]-$posttime[1])<0){$mytime[2]--;$mytime[1]+=60;} $difference[1]=($mytime[1]-$posttime[1]); if(($mytime[2]-$posttime[2])<0){$mytime[3]--;$mytime[2]+=24;} $difference[2]=($mytime[2]-$posttime[2]); if(($mytime[3]-$posttime[3])<0){$mytime[4]--;$mytime[3]+=31;} $difference[3]=($mytime[3]-$posttime[3]); if(($mytime[4]-$posttime[4])<0){$mytime[5]--;$mytime[4]+=12;} $difference[4]=($mytime[4]-$posttime[4]); $difference[5]=($mytime[5]-$posttime[5]); $i=0;$d=''; my @englishtime=('second(s)','minute(s)','hour(s)','day(s)','month +(s)','year(s)'); #for(@difference){$d.="$_ $mytimeime[$i] ";$i++;} $d="[$difference[0]s:$difference[1]m:$difference[2]h - $difference +[3]d/$difference[4]m/$difference[5]y]"; return $d;
I know its incredibly kludgy and barely runs under use strict, which is mostly why im looking for a good module to use.

Replies are listed 'Best First'.
(ar0n: Date::Calc ) Re: Date difference?
by ar0n (Priest) on Apr 28, 2002 at 22:44 UTC
    At the risk of giving you a RTFM answer, see Date::Calc, and more specifically Delta_DHMS:
    use Date::Calc qw/Delta_DHMS/; ... my @date_one = qw/2002 04 25 23 12 40/; my @date_two = qw/2002 03 23 15 25 21/; my ($dd, $dh, $dm, $ds) = Delta_DHMS(@date_one, @date_two);
      I'm fond of Date::Calc, so I played with your example a bit since I had never used it that way myself. I found something that seemed curious to me. Your example has the delta as negative, since @date_one is before @date_two. That makes sense. But Date::Calc seems to cause each and every element returned by Delta_DHMS to be negative. Should just the first element be negative?
      [chicks]$ perl x -33:-7:-47:-19 33:7:47:19 [chicks]$ cat x #!/usr/bin/perl -w use Date::Calc qw/Delta_DHMS/; my @date_one = qw/2002 04 25 23 12 40/; my @date_two = qw/2002 03 23 15 25 21/; my ($dd, $dh, $dm, $ds) = Delta_DHMS(@date_one, @date_two); print "$dd:$dh:$dm:$ds\n"; ($dd, $dh, $dm, $ds) = Delta_DHMS(@date_two, @date_one); print "$dd:$dh:$dm:$ds\n";
        This is explained in  perldoc Date::Calc
        * "($Dd,$Dh,$Dm,$Ds) = Delta_DHMS($year1,$month1,$day1, $hour1,$min1,$sec1, $year2,$month2,$day2, $hour2,$min2,$sec2);" This function returns the difference in days, hours, minutes and seconds between the two given dates with times. All four return values will be positive if the two dates are in chronological order, i.e., if date #1 comes chronologically BEFORE date #2, and negative (in all four return values!) if the order of t +he two dates is reversed. This is so that the two functions ""Delta_DHMS()"" and ""Add_Delta_DHMS()"" (description see further below) are complementary, i.e., mutually inverse: Add_Delta_DHMS(@date1,@time1, Delta_DHMS(@date1,@time1, @date2,@ti +me2)) yields ""(@date2,@time2)"" again, whereas Add_Delta_DHMS(@date2,@time2, map(-$_, Delta_DHMS(@date1,@time1, @date2,@time2))) yields ""(@date1,@time1)"", and Delta_DHMS(@date1,@time1, Add_Delta_DHMS(@date1,@time1, @delta)) yields ""@delta"" again. The result is zero (in all four return values) if the two dates and times are identical.


Re: Date difference?
by davorg (Chancellor) on Apr 29, 2002 at 08:18 UTC

    Coming a bit late to this thread, but I just need to add a plug forMatts' criminally underused Time::Piece module. If you subtract one Time::Piece object from another, then the result is a Time::Seconds object which can be displayed in various ways. An example from the docs:

    use Time::Object; use Time::Seconds; my $t = localtime; $t += ONE_DAY; my $t2 = localtime; my $s = $t - $t2; print "Difference is: ", $s->days, "\n";
      ++! I didn't know about that one. Very useful - thank you for the link!

      Wiliam Stephens <>
Re: Date difference?
by johannz (Hermit) on Apr 29, 2002 at 02:35 UTC

    Also risking another RTFM answer, Date::Manip tends to my toolbox of choice for date manipulation. I tried the following with no problems:

    use Date::Manip; #use warnings; # Skipped for quick example #use strict; # Skipped for quick example Date::Manip::Date_Init('TZ=US/Mountain'); print johannz('yesterday'); sub johannz { return Delta_Format(DateCalc('today',shift()), 0, '%sv s:%mv m:%hv + h - %dv d/%Mv M/%yv y'); }

    I like Date::Manip because it accepts such a wide variety of date formats. It's a DWIM module in that regard.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://162721]
Approved by Ovid
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others taking refuge in the Monastery: (5)
As of 2020-08-15 12:49 GMT
Find Nodes?
    Voting Booth?
    Which rocket would you take to Mars?

    Results (78 votes). Check out past polls.