Hey,
That really sucks huh? And when 2038 (I think) rolls around, the bits will
be maxed out! Amazing how they can create such a solid OS and not even
consider these things.
Anyway, I found a solution at php.net.
Check it out at
http://www.php.net/mktime in the comments, or read below!!
Thanks,
Mike
----------------------------------------------------------
If you want to calculate dates before 1970 and your OS doesn't support it
(Windows and Linux), you can easily write your own wrapper to mktime to do
the calculation. The idea is to find a date range in the 1970-2037 time
frame that is the same as your year prior to 1970 (both years start on the
same day of the week and leap years are the same), then add that number of
years to your year value before calling mktime() and then subtract the
corresponding number of seconds from the mktime() result (including the
appropriate number of leap seconds). This way old guys like me (born in
1963) can get a valid number back from mktime() and we can figure out how
old we are in seconds. :-) You can go all the way back to 1902 if you
want.
The mapping is as follows:
1902-1951 = 1986-2035
1952-1969 = 1980-1997
By matching starting day of week for the year and leap years then we should
calculate daylight time correctly (assuming that we have the right rules
set). There's a special hack in the code to turn off daylight time prior to
1942 for date().
Here's the code that we're using now:
//
// Replacement for mktime that does dates before 1970
//
function MakeTime()
{
$objArgs = func_get_args();
$nCount = count($objArgs);
if ($nCount < 7)
{
$objDate = getdate();
if ($nCount < 1)
$objArgs[] = $objDate["hours"];
if ($nCount < 2)
$objArgs[] = $objDate["minutes"];
if ($nCount < 3)
$objArgs[] = $objDate["seconds"];
if ($nCount < 4)
$objArgs[] = $objDate["mon"];
if ($nCount < 5)
$objArgs[] = $objDate["mday"];
if ($nCount < 6)
$objArgs[] = $objDate["year"];
if ($nCount < 7)
$objArgs[] = -1;
}
$nYear = $objArgs[5];
$nOffset = 0;
if ($nYear < 1970)
{
if ($nYear < 1902)
return 0;
else if ($nYear < 1952)
{
$nOffset = -2650838400;
$objArgs[5] += 84;
// Apparently dates before 1942 were never DST
if ($nYear < 1942)
$objArgs[6] = 0;
}
else
{
$nOffset = -883612800;
$objArgs[5] += 28;
}
}
return call_user_func_array("mktime", $objArgs) + $nOffset;
}
In Linux, the values returned will work just fine with date() and I believe
that strftime() should work too, but Windows doesn't like the negative
values at all. We had to write a replacement for strtotime since it appears
to call mktime() to come up with the final result.
I hope that this helps someone.
- todd
"Joshua Beall" <jb****@donotspam.remove.me.heraldic.us> wrote in message
news:pD2Wd.77751$wc.33781@trnddc07...
Hi All,
I am wondering what the best way to determine an age of something/somone
is. For instance, let's say I have two dates:
1985-07-19
2003-11-30
Now, I want to determine the interval in years, and for each fraction of a
year, days. I won't mess with months because they can have variable
length, or if I do measure months I will simply say that a month is 30
days.
So here's my problem: normally when doing date comparison I simply convert
the dates to a UNIX timestamp. This allows me to get the number of
seconds from one date to the other. This is fine for small date ranges.
For instance, let's say I had these dates:
1985-07-19
1985-11-15
Once I get the number of seconds, I simply divide by 86400 in order to
determine the number of days.
But things get complicated once the date range gets large enough, because
I now have to worry about leap years. Every 4 years we have an extra
86400 seconds in a year. So how do I handle this case? If I want to know
the number years and days for two dates that are far apart, like the two I
listed at the beginning, what should I be doing? How do I account for
leap years, where there is an extra day?
I'm looking at PHP's builtin date and time functions, and nothing seems to
handle the case I've got in mind. Do I have to roll my own solution here
and check to see whether or not each year in my daterange is a leap year?
Thanks for any pointers!
Sincerely,
-Josh