Replacement for Add_Delta_Days

Published on April 22, 2009

One of my Perl scripts here at work used the Add_Delta_Days subroutine from the Date::Calc module to do some calendar date arithmetic. I’m in the process of building a new machine on which this script will run, and I don’t have access to an external network. Unfortunately, the install process for Date::Calc is fairly difficult. The module relies on a C library which must be compiled with the same compiler as was used to build the local Perl install. To make matters worse, the modules that Date::Calc is dependent on have similar requirements. As a result, I decided to skip installing this non-standard module, and instead use a home-brew replacement. It turns out that Add_Delta_Days is fairly straightforward to replace:

use Time::Local; # Standard module

sub addDaysToDate
{
    my ($y, $m, $d, $offset) = @_;

    # Convert the incoming date to epoch seconds
    my $TIME = timelocal(0, 0, 0, $d, $m-1, $y-1900);

    # Convert the offset from days to seconds and add
    # to our epoch seconds value
    $TIME += 60 * 60 * 24 * $offset;

    # Convert the epoch seconds back to a legal 'calendar date'
    # and return the date pieces
    my @values = localtime($TIME);
    return ($values[5] + 1900, $values[4] + 1, $values[3]);
}

You call this subroutine like this:

my $year = 2009;
my $month = 4;
my $day = 22;

my ($nYear, $nMonth, $nDay) = addDaysToDate($year, $month, $day, 30);

This subroutine isn’t a one-to-one replacement, obviously. Unlike Date::Calc, my home-brew subroutine suffers from the Year 2038 problem (at least on 32-bit operating systems). It likewise can’t go back in time by incredible amounts (I’m bound to the deltas around the epoch). However, this workaround saves me a bunch of setup time, and works just as well.

4 Comments

kip

Not sure how Date::Calc handles daylight saving time, but that might be something to consider. Adding 60 days to 11:30 PM on March 1 without factoring in DST might give you 12:30 AM 61 days later, because of the missing hour that was “sprung forward” over. And a similar same thing would happen in the fall, if you start with 12:30 AM you’d get 11:30 PM 59 days later.

I’m guessing that Date::Calc does indeed take all of that into consideration. The +/- 1 day around daylight savings doesn’t matter much for what I’m using it for, so this works just fine. All I really need is a ballpark.

I also see a Perl-port of the Date::Calc module: Date::Pcalc. The install process for that is much simpler.

I checked the source for Date::Pcalc and looked at the Add_Delta_Days routine. It does not handle daylight savings time, simply because it doesn’t take the time into effect. The only values passed in are the current date, making things much simpler.

Comments are closed.

Copyright © 2004-2018 Jonah Bishop. Hosted by DreamHost.