#17123 [Com]: mktime(), localtime(), strtotime(), etc. are broken for dates <1970 in Win32
| From: | percy_H_ at _AT_majiclab_DOHT_ dot _KOM | Date: | Thu, 01 Aug 2002 14:56:31 +0000 |
| Subject: | #17123 [Com]: mktime(), localtime(), strtotime(), etc. are broken for dates <1970 in Win32 | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-15742@lists.php.net to get a copy of this message | ||
ID: 17123
Comment by: percy_H_@_AT_majiclab_DOHT_._KOM
Reported By: jasonh@trurocollege.ac.uk
Status: Verified
Bug Type: Date/time related
Operating System: WinNT5.0
PHP Version: 4.2.0
New Comment:
I have 4.0.6 on several machines (3 I think), and I have the same
problem on all of them (I have Windows 2000 on all of them). As much
as I want to convert my server to a linux box, it still leaves me two
computers with Windows 2000 and this bug. I had one idea, but since I
don't have 4.2.0 I can't work on it yet. With the new W32 API
capabilities of 4.2.0, would it not be possible to use some Windows API
functions to parse date/time information rather than the included PHP
functions? Obviously, Windows can handle the dates. I use JavaScript
a lot and it has a range of approximately 275,000 years before and
after 1970. I tested my valid range yesterday using the PHP functions,
I could go from 1970 to about 2037. Wow. What about all the people
that were born before 1970? Older than 32 years...
Anyway, when I get home I will download 4.2.0 and then start hacking
away at using the PROPER Windows API functions for date/time since PHP
seems to be wanting to use the ones that don't work.
Hope something gets figured out, even if I have to program my own DLL
to make it work... :)
-Percy
Previous Comments:
------------------------------------------------------------------------
[2002-07-04 16:08:25] eru@php.net
Verified during the Bughunt.
------------------------------------------------------------------------
[2002-06-22 14:39:43] ldprice@attbi.com
mktime error with the following code:
mktime returns -1 for years less than 1970
Windows XP Pro, PHP 4.1.1, Microsoft-IIS/5.1
Windows 2000 Server, PHP 4.2.1, Apache/2.0.39 (Win32)
Date of Birth:
Warning: unexpected error in date() in
C:\catalog\includes\functions\general.php on line 531
function tep_date_short($raw_date) {
if ( ($raw_date == '0000-00-00 00:00:00') || ($raw_date == '') )
return false;
// remove the first digit if it is 0 - as php treats these as Octals
$year = substr($raw_date, 0, 4);
$month = substr($raw_date, 5, 2); if (substr($month, 0, 1) == '0')
$month = substr($month, 1);
$day = substr($raw_date, 8, 2); if (substr($day, 0, 1) == '0') $day
= substr($day, 1);
$hour = substr($raw_date, 11, 2); if (substr($hour, 0, 1) == '0')
$hour = substr($hour, 1);
$minute = substr($raw_date, 14, 2); if (substr($minute, 0, 1) ==
'0') $minute = substr($minute, 1);
$second = substr($raw_date, 17, 2); if (substr($second, 0, 1) ==
'0') $second = substr($second, 1);
return date(DATE_FORMAT, mktime($hour, $minute, $second, $month,
$day, $year));
------------------------------------------------------------------------
[2002-06-02 19:06:49] k.schroeder@php.net
Reopened in reaction of new comment under #17472.
Regards, Kai
------------------------------------------------------------------------
[2002-05-24 20:31:17] derick@php.net
Fixed by documenting this.
------------------------------------------------------------------------
[2002-05-09 12:04:11] jasonh@trurocollege.ac.uk
We've struggled with the fact that mktime(), strtotime(), localtime(),
etc. are broken for dates <1970 under Win32. Below is some PHP code
that shows how this might be worked around to generate (and use)
negative Unix timestamps under Windows. It would be nice if this idea
could be incorporated into all the timestamp functions (since we don't
want to have to rewrite something like strtotime() which is quite
essential for us in deciphering MSSQL datetime fields).
The concept is to fiddle dates before 1970 to be dates 56 years later
when supplying them to the broken Win32 native functions, and then
fiddle the results back to the correct values. This will ensure that
leap year counts are still correct and give dates on the correct days
of the week. The code below shows fiddling the generation of a full
timestamp (mktime()) and fiddling the interpretation of those full
timestamps (localtime()).
---------
$epoch2 = mktime(0,0,0,1,1,2026);
function mymktime($hr,$mi,$sc,$m,$d,$y) {
global $epoch2;
$fiddle = 0;
if($y <= 1970) { // Should be just < 1970, but this will help cope
with 0 month or 0 day
$fiddle = $epoch2;
$y = $y + 56;
}
return mktime($hr,$mi,$sc,$m,$d,$y) - $fiddle;
}
function mylocaltime($ts,$assoc) {
global $epoch2;
$fiddle = false;
if($ts < 0 && $ts != -1) {
$fiddle = true;
$ts += $epoch2;
}
$res = localtime($ts,$assoc);
if($fiddle)
$res[$assoc?"tm_year":5] -= 56;
return $res;
}
------------------------------------------------------------------------
--
Edit this bug report at http://bugs.php.net/?id=17123&edit=1