Perl Cookbook Authors: Christiansen T.,  Torkington N. Published year: 2003 Pages: 65-66/501

### Recipe 3.3 Converting Epoch Seconds to DMYHMS

#### 3.3.1 Problem

You have a date and time in Epoch seconds, and you want to calculate individual DMYHMS values from it.

#### 3.3.2 Solution

Use the localtime or gmtime functions, depending on whether you want the date and time in UTC or your local time zone.

(\$seconds, \$minutes, \$hours, \$day_of_month, \$month, \$year,
\$wday, \$yday, \$isdst) = localtime(\$time);

The standard Time::timelocal and Time::gmtime modules override the localtime and gmtime functions to provide named access to the individual values.

use Time::localtime;        # or Time::gmtime
\$tm = localtime(\$TIME);     # or gmtime(\$TIME)
\$seconds = \$tm->sec;
# ...

#### 3.3.3 Discussion

The localtime and gmtime functions return strange year and month values; the year has 1900 subtracted from it, and 0 is the month value for January. Be sure to correct the base values for year and month, as this example does:

(\$seconds, \$minutes, \$hours, \$day_of_month, \$month, \$year,
\$wday, \$yday, \$isdst) = localtime(\$time);
printf("Dateline: %02d:%02d:%02d-%04d/%02d/%02d\n",
\$hours, \$minutes, \$seconds, \$year+1900, \$month+1,
\$day_of_month);

We could have used the Time::localtime module to avoid the temporary variables :

use Time::localtime;
\$tm = localtime(\$time);
printf("Dateline: %02d:%02d:%02d-%04d/%02d/%02d\n",
\$tm->hour, \$tm->min, \$tm->sec, \$tm->year+1900,
\$tm->mon+1, \$tm->mday);

The localtime function in perlfunc (1) and Chapter 29 of Programming Perl ; the documentation for the standard Time::localtime and Time::gmtime modules; convert in the other direction using Recipe 3.3

### Recipe 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):

(\$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 :

(\$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:

(\$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:

(\$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