Date::Span - deal with date/time ranges than span multiple dates


version 1.129


 use Date::Span;

 @spanned = range_expand($start, $end);

 print "from $_->[0] to $_->[1]\n" for (@spanned);


This module provides code for dealing with datetime ranges that span multiple calendar days. This is useful for computing, for example, the amount of seconds spent performing a task on each day. Given the following table:

  event   | begun            | ended
  loading | 2004-01-01 00:00 | 2004-01-01 12:45
  venting | 2004-01-01 12:45 | 2004-01-02 21:15
  running | 2004-01-02 21:15 | 2004-01-03 00:00

We may want to gather the following data:

  date       | event   | time spent
  2004-01-01 | loading | 12.75 hours
  2004-01-01 | venting | 11.25 hours
  2004-01-02 | venting | 21.25 hours
  2004-01-02 | running |  2.75 hours

Date::Span takes a data like the first and produces data more like the second. (Details on exact interface are below.)


This library should run on perls released even a long time ago. It should work on any version of perl released in the last five years.

Although it may work on older versions of perl, no guarantee is made that the minimum required version will not be increased. The version may be increased for any reason, and there is no promise that patches will be accepted to lower the minimum required perl.



  my @durations = range_durations($start, $end)

Given $start and $end as timestamps (in epoch seconds), range_durations returns a list of arrayrefs. Each arrayref is a date (expressed as epoch seconds at midnight) and the number of seconds for which the given range intersects with the date.


  my @endpoint_pairs = range_expand($start, $end);

Given $start and $end as timestamps (in epoch seconds), range_durations returns a list of arrayrefs. Each arrayref is a start and end timestamp. No pair of start and end times will cross a date boundary, and the set of ranges as a whole will be identical to the passed start and end.


  my ($start, $end) = range_from_unit(@date_unit)

@date_unit is a specification of a unit of time, in the form:

 @date_unit = ($year, $month, $day, $hour, $minute);

Only $year is mandatory; other arguments may be added, in order. Month is given in the range (0 .. 11). This function will return the first and last second of the given unit.

A code reference may be passed as the last object. It will be used to convert the date specification to a starting time. If no coderef is passed, a simple one using Time::Local (and timegm) will be used.


This code was just yanked out of a general purpose set of utility functions I've compiled over the years. It should be refactored (internally) and further tested. The interface should stay pretty stable, though.


Ricardo SIGNES <>


Ricardo Signes <>


This software is copyright (c) 2004 by Ricardo SIGNES.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.