#!/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; }