Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Previous Day Script Running on Jan 1 and leap years 1

Status
Not open for further replies.

wdellin

MIS
Feb 8, 2002
36
US
I have a script that gets current date using localtime and previous day using localtime - 60 * 60 * 24. This forum was very helpful in the commands to do this.

My question is will I get the correct previous day on January 1? What about March 1 in leap years. Not being that familiar with Perl, I'm not sure if perl somehow accomodates this or if there is additional code I need to get the correct previous day in these two situations.

Any help or direction would be appreciated.











 
From Perl Cookbook:
3.5. Difference of Two Dates
3.5.1. Problem
You need to find the number of days between two dates or times.

3.5.2. Solution
If your dates are in Epoch seconds and fall in the range Fri Dec 13 20:45:52 1901 to Tue Jan 19 03:14:07 2038 (inclusive), subtract one from the other and convert the seconds to days:

$seconds = $recent - $earlier;
If you have distinct DMYMHS values or are worried about the range limitations of Epoch seconds, use the Date::Calc module from CPAN. It can calculate the difference between dates:

use Date::Calc qw(Delta_Days);
$days = Delta_Days( $year1, $month1, $day1, $year2, $month2, $day2);
It also calculates the difference between a pair of dates and times:

use Date::Calc qw(Delta_DHMS);
($days, $hours, $minutes, $seconds) =
Delta_DHMS( $year1, $month1, $day1, $hour1, $minute1, $seconds1, # earlier
$year2, $month2, $day2, $hour2, $minute2, $seconds2); # later
3.5.3. Discussion
One problem with Epoch seconds is how to convert the large integers back to forms that people can read. The following example shows one way of converting an Epoch seconds value back to its component numbers of weeks, days, hours, minutes, and seconds:

$bree = 361535725; # 16 Jun 1981, 4:35:25
$nat = 96201950; # 18 Jan 1973, 3:45:50

$difference = $bree - $nat;
print "There were $difference seconds between Nat and Bree\n";
There were 265333775 seconds between Nat and Bree

$seconds = $difference % 60;
$difference = ($difference - $seconds) / 60;
$minutes = $difference % 60;
$difference = ($difference - $minutes) / 60;
$hours = $difference % 24;
$difference = ($difference - $hours) / 24;
$days = $difference % 7;
$weeks = ($difference - $days) / 7;

print "($weeks weeks, $days days, $hours:$minutes:$seconds)\n";
(438 weeks, 4 days, 23:49:35)
Date::Calc's functions can ease these calculations. The Delta_Days function returns the number of days between two dates. It takes the two dates as a list: year, month, day. The dates are given chronologically—earliest first.

use Date::Calc qw(Delta_Days);
@bree = (1981, 6, 16); # 16 Jun 1981
@nat = (1973, 1, 18); # 18 Jan 1973
$difference = Delta_Days(@nat, @bree);
print "There were $difference days between Nat and Bree\n";
There were 3071 days between Nat and Bree
The Delta_DHMS function returns a four-element list corresponding to the number of days, hours, minutes, and seconds between the two dates you give it.

use Date::Calc qw(Delta_DHMS);
@bree = (1981, 6, 16, 4, 35, 25); # 16 Jun 1981, 4:35:25
@nat = (1973, 1, 18, 3, 45, 50); # 18 Jan 1973, 3:45:50
@diff = Delta_DHMS(@nat, @bree);
print "Bree came $diff[0] days, $diff[1]:$diff[2]:$diff[3] after Nat\n";
Bree came 3071 days, 0:49:35 after Nat
 
dmazzini

I appreciate all the information you provided. As I said before I'm not that familiar with Perl so all information I receive helps me very much.

It appears that all the examples are trying to find the difference between two dates. I'm trying to find out what the "date" is when I subtract 1 day from current date. If I use localtime(let's set it at 01 01 2005) and subtract 60 * 60 * 24 (one day), is the answer 12 31 2004? Another example is for leap year, if localtime is 03 01 2004 and I subtract 60 * 60 * 24, is the answer 02 29 2004? I don't have a way that I know of to test this since localtime is neither of the dates listed above. My routine is looking for current date and yesterday's date. This routine works for all dates so far, but the question is will it work on January 1, 2005 and the next time we have a leap year.
Thanks



 
If you call localtime() (no arguments) or localtime(time) it returns info about the current date and time. If you call localtime(time - 60 * 60 * 24) or localtime(time - 86400), you will get info for 1 day earlier. E.g.,
Code:
#!perl
use strict;
use warnings;

my @keys = qw(sec min hour mday mon year wday yday isdst);
my (%t1, %t2);
@t1{@keys}= localtime(time);
@t2{@keys} = localtime(time - 60 * 60 * 24);
print "field\tt1\tt2\n=====\t==\t==\n";	
for (@keys) {
    print "$_\t$t1{$_}\t$t2{$_}\n";
}
Output:
Code:
field   t1      t2
=====   ==      ==      
sec     26      26
min     25      25
hour    0       0
mday    27      26
mon     9       9
year    104     104
wday    3       2
yday    300     299
isdst   1       1
Note that mday, wday, and yday are all cranked back by one in the %t2 hash.

 
wdellin

The whole point of holding dates and times using seemingly bizarre formats such as the number of seconds in the epoch is that it reduces all the calculations to simple adding and subtraction.

IBM use the number of seconds since the Gregorian Calendar was introduced in the 15th century, SAS uses 1/1/1960, and Excel uses fractions of a day since 1/1/1900 under Windows and 1/1/1904 on a Mac (no, I don't know why). But they all do it for the same reason - whenever a date needs to be displayed, it gets converted to 'external' format. The conversion routines figure out what day it is, including new years, leap years, and even leap centuries. They've done the hard work, so you don't have to...
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top