How can I calculate the number of days between two dates in Perl?

There seems to be quite a bit of confusion because, depending on what you are trying to accomplish, “the number of days between two dates” can mean at least two different things:

  1. The calendar distance between the two dates.
  2. The absolute distance between the two dates.

As an example and to note the difference, assume that you have two DateTime objects constructed as follows:

use DateTime;

sub iso8601_date {
  die unless $_[0] =~ m/^(\d\d\d\d)-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)Z$/;
  return DateTime->new(year => $1, month => $2, day => $3,
    hour => $4, minute => $5, second => $6, time_zone  => 'UTC');
}

my $dt1 = iso8601_date('2014-11-04T23:35:42Z');
my $dt2 = iso8601_date('2014-11-07T01:15:18Z');

Note that $dt1 is quite late on a Tuesday, while $dt2 is very early on the following Friday.

If you want the calendar distance use:

my $days = $dt2->delta_days($dt1)->delta_days();
print "$days\n" # -> 3

Indeed, between, Tuesday and Friday there are 3 days. A calendar distance of 1 means “tomorrow” and a distance of -1 means “yesterday”. The “time” part of the DateTime objects is mostly irrelevant (except perhaps if the two dates fall on different time zones, then you would have to decide what “the calendar distance” between those two dates should mean).

If you want the absolute distance then instead use:

my $days = $dt2->subtract_datetime_absolute($dt1)->delta_seconds / (24*60*60);
print "$days\n"; # -> 2.06916666666667

Indeed, if you want to split the time between the two dates in 24-hour chunks, there are only about 2.07 days between them. Depending on your application, you might want to truncate or round this number. The “time” part of the DateTime objects is very relevant, and the expected result is well defined even for dates on different time zones.

Leave a Comment