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

I must not understand how subtraction works with DateTime. Using one method, I get 4 days and using another, apparently equivalent, method, I get 5 days duration:
main::(a.pl:49): my $first_time_date_time=DateTime::Format::ISO8601 +->parse_datetime($first_time); + + DB<2> p $first_time 2013-08-01T20:10:31 + + DB<3> n main::(a.pl:50): my $last_time_date_time=DateTime::Format::ISO8601- +>parse_datetime($last_time); + + DB<3> p $last_time 2013-08-06T20:09:34 + + DB<4> n main::(a.pl:51): my $duration=$last_time_date_time->subtract_dateti +me($first_time_date_time); + + DB<4> main::(a.pl:52): my $days=$duration->days; + + DB<4> p $duration DateTime::Duration=HASH(0x1a2f268) + + DB<5> p $duration->in_units('days') 4 + + DB<6> x $duration->deltas() 0 'months' 1 0 2 'days' 3 4 4 'minutes' 5 1439 6 'seconds' 7 3 8 'nanoseconds' 9 0 + + DB<7> $d=$last_time_date_time->delta_days($first_ +time_date_time) + + DB<8> p $d DateTime::Duration=HASH(0x1e1e2e8) + + DB<9> p $d->in_units('days') 5

Replies are listed 'Best First'.
Re: Inconsistent results of subtraction with DateTime?
by rjt (Curate) on Aug 07, 2013 at 19:37 UTC

    DateTime says:

    • date vs datetime math

    If you only care about the date (calendar) portion of a datetime, you should use either delta_md() or delta_days(), not subtract_datetime().

    In short, subtract_datetime gives you an answer that includes days, minutes, and seconds between the two times. But delta_days essentially chops off the "time" part of your DateTime object and then does the subtraction, so you only get days.

    To see for yourself, try dumping the DateTime::Duration objects:

    use DateTime; use DateTime::Format::ISO8601; my ($first, $last) = map { DateTime::Format::ISO8601->parse_dateti +me($_) } qw < 2013-08-01T20:10:31 2013-08-06T20:09:34 + >; my ($sub, $days) = map { $last->$_($first) } qw< subtract_datetime delta_days >; printf "%12s %5s | %-5s\n", 'Value', 'sub', 'days'; printf "%.21s+%.8s\n", ('-'x21)x2; for (qw< months days minutes seconds nanoseconds >) { printf "%12s : %5d | %-5d\n", $_, $sub->{$_}, $days->{$_}; }

    Output:

    Value sub | days ---------------------+-------- months : 0 | 0 days : 4 | 5 minutes : 1439 | 0 seconds : 3 | 0 nanoseconds : 0 | 0
    use strict; use warnings; omitted for brevity.
Re: Inconsistent results of subtraction with DateTime?
by Anonymous Monk on Aug 07, 2013 at 19:08 UTC

    Aug 6 is 5 days later than Aug 1 (Delta_days)

    Aug 6 @ 8:10 is 4 days and 23.98 hours later than Aug 1 @ 8:09 (time subtraction)

    ... Makes sense to me. You should check the documentation to be sure.

      Ah, thanks. I had made the mistake of thinking that the times were identical between the two datetimes (I didn't even look at the output of the 'p' debugger commands I was so "sure") when, in fact, they were offset from each other by some minutes.