note 38068 added to function.mktime
| From: | todd at buiten dot com | Date: | Sun, 07 Dec 2003 06:14:44 +0000 |
| Subject: | note 38068 added to function.mktime | ||
| Groups: | php.notes | ||
| Request: | Send a blank email to php-notes+get-61584@lists.php.net to get a copy of this message | ||
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
----
Manual Page -- http://www.php.net/manual/en/function.mktime.php
Edit -- http://master.php.net/manage/user-notes.php?action=edit+38068
Delete -- http://master.php.net/manage/user-notes.php?action=delete+38068&report=yes
Reject -- http://master.php.net/manage/user-notes.php?action=reject+38068&report=yes
Search -- http://master.php.net/manage/user-notes.php