Adding to or Subtracting from a Date (Perl Cookbook, 2nd Edition)

## 3.4. Adding to or Subtracting from a Date

### 3.4.1. Problem

You have a date and time and want to find the date and time of some period in the future or past.

### 3.4.2. Solution

Simply add or subtract Epoch seconds:

>     $when = $now + $difference;
>     $then = $now - $difference;

If you have distinct DMYHMS values, use the CPAN Date::Calc module. If you're doing arithmetic with days only, use `Add_Delta_Days` (`$offset` is a positive or negative integral number of days):

>     use Date::Calc qw(Add_Delta_Days);
>     ($y2, $m2, $d2) = Add_Delta_Days($y, $m, $d, $offset);

If you are concerned with hours, minutes, and seconds (in other words, times as well as dates), use `Add_Delta_DHMS`:

>     use Date::Calc qw(Add_Delta_DHMS);
>     ($year2, $month2, $day2, $h2, $m2, $s2) =
>         Add_Delta_DHMS( $year, $month, $day, $hour, $minute, $second,
>                     $days_offset, $hour_offset, $minute_offset, $second_offset );

### 3.4.3. Discussion

Calculating with Epoch seconds is easiest, disregarding the effort to get dates and times into and out of Epoch seconds. This code shows how to calculate an offset (55 days, 2 hours, 17 minutes, and 5 seconds, in this case) from a given base date and time:

>     $birthtime = 96176750;                  # 18/Jan/1973, 3:45:50 am
>     $interval = 5 +                         # 5 seconds
>                 17 * 60 +                   # 17 minutes
>                 2  * 60 * 60 +              # 2 hours
>                 55 * 60 * 60 * 24;          # and 55 days
>     $then = $birthtime + $interval;
>     print "Then is ", scalar(localtime($then)), "\n";
>     Then is Wed Mar 14 06:02:55 1973

We could have used Date::Calc's `Add_Delta_DHMS` function and avoided the conversion to and from Epoch seconds:

>     use Date::Calc qw(Add_Delta_DHMS);
>     ($year, $month, $day, $hh, $mm, $ss) = Add_Delta_DHMS(
>         1973, 1, 18, 3, 45, 50, # 18/Jan/1973, 3:45:50 am
>                  55, 2, 17, 5); # 55 days, 2 hrs, 17 min, 5 sec
>     print "To be precise: $hh:$mm:$ss, $month/$day/$year\n";
>     To be precise: 6:2:55, 3/14/1973

As usual, we need to know the range of values the function expects. `Add_Delta_DHMS` takes a full year value—that is, one that hasn't had 1900 subtracted from it. The month value for January is 1, not 0. Date::Calc's `Add_Delta_Days` function expects the same kind of values:

>     use Date::Calc qw(Add_Delta_Days);
>     ($year, $month, $day) = Add_Delta_Days(1973, 1, 18, 55);
>     print "Nat was 55 days old on: $month/$day/$year\n";
>     Nat was 55 days old on: 3/14/1973

### 3.4.4. See Also

The documentation for the CPAN module Date::Calc

Copyright © 2003 O'Reilly & Associates. All rights reserved.