#!/usr/local/bin/perl
# datemath.pl
# desc: contains example code for datemath
# wordsettings:
# end_autoz
use Time::Local;
use POSIX;
### Note: the date math and manipulation shown here may not work on a PC.
### this is probably due to differences in the CPU architecture.
### These routines do run correctly on a Solaris box.
### demonstrating basic time/date call and data manipulation
# get the current date and time
($sec, $min, $hour, $day, $month, $year, $wday, $yday, $isdst) = localtime;
# once retrieved,
# time values start at 0
# day of month number starts at 0
# add 1900 to year when getting that
# convert the current date to "Voyager" format
$today = sprintf ("%4.4d.%2.2d.%2.2d", $year+1900, $month+1, $day);
# get the current date and time in raw format (in seconds)
$timenow = time;
# now find out the date 10 days ago
# there are 86,400 seconds in a day
$timeminus10 = $timenow - (86400 * 10);
# convert this computed raw date+time value into usable pieces
($sec, $min, $hour, $day, $month, $year, $wday, $yday, $isdst) = localtime($timeminus10);
# and convert it to "Voyager" format and output the results
$todayminus10 = sprintf ("%4.4d.%2.2d.%2.2d", $year+1900, $month+1, $day);
printf ("\ntoday is %s, and ten days ago was %s\n", $today, $todayminus10);
### doing math with an arbitrary date
$year = 2001;
$month = 12;
$day = 31;
printf ("\n%4.4d.%2.2d.%2.2d start date\n", $year, $month, $day);
# convert to native format; "noise" values for time part
$time = timelocal('10','10','10', $day, $month-1, $year);
# add a day
$time += 86400;
# convert to usable values and output it
($sec, $min, $hr, $day, $month, $year) = localtime($time);
printf ("%4.4d.%2.2d.%2.2d start date, one day later\n", $year+1900, $month+1, $day);
### the computedate routine was written to take an arbitrary date, and
### output the resulting date if N days are added to or subtracted from
### the input date.
$daynow = '2006.04.26';
$dayadjust = -160;
$daythen = computedate($daynow, $dayadjust);
print "\ndaynow is $daynow, the difference is $dayadjust day(s),\nand the resulting date is $daythen\n";
### here's an example of using the computedatesdiff routine
### given two input dates, it computes the difference between them in years
$daystart = '2005.04.26';
$daythen = '2008.08.08';
$yeardiff = computedatesdiff($daystart, $daythen);
print "\ndaystart is $daystart and daythen is $daythen,\nand the difference, in years, is $yeardiff\n";
###### SUBROUTINES SECTION
sub computedate
# input: date, days date in format YYYY.MM.DD
# output: date result of input date + days
{
my ($cdate, $delta) = @_;
my $blankdate = ' . . ';
# in case of incoming blank date
if ($cdate eq $blankdate) {return $blankdate;}
my $day = substr($cdate, 8, 2);
my $month = substr($cdate, 5, 2) - 1;
my $year = substr($cdate, 0, 4) - 1900;
my ($sec, $min, $hr) = (10, 10, 10);
# convert for math, do math, and convert back
my $ctime = mktime($sec, $min, $hr, $day, $month, $year);
$ctime += $delta * 86400; # add/subtract specified number of days
($sec, $min, $hr, $day, $month, $year) = localtime($ctime);
my $dateout = sprintf ("%4.4d.%2.2d.%2.2d", $year+1900, $month+1, $day);
return $dateout;
}
sub computedatesdiff
# input: two dates
# output: difference between the two in years
# CAUTION: this date math may not work on a PC (16/32 bitness?)
# dates in format YYYY.MM.DD
{
my ($adate, $bdate) = @_;
# extract date components
my $aday = substr($adate, 8, 2);
my $amonth = substr($adate, 5, 2);
my $ayear = substr($adate, 0, 4);
my $bday = substr($bdate, 8, 2);
my $bmonth = substr($bdate, 5, 2);
my $byear = substr($bdate, 0, 4);
my ($sec, $min, $hr) = (0, 0, 0);
# convert for math
my $atime = timelocal($sec, $min, $hr, $aday, $amonth-1, $ayear-1900);
my $btime = timelocal($sec, $min, $hr, $bday, $bmonth-1, $byear-1900);
# do the math
my $delta = abs($atime - $btime);
$delta = floor($delta / (86400 * 365));
# output the difference in years
return $delta;
}