|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2002-05-09 12:04 UTC] jasonh at trurocollege dot ac dot 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;
}
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Sat Oct 25 18:00:02 2025 UTC |
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));Sadly, I had to rebuild date function to be compatible with mylocal.. here's the code, extensions are welcome: function mydate($format, $timestamp = null) { if ($timestamp == null) { return @date($format); } if ($timestamp > -1) { return @date($format, $timestamp); } $dateArr = $this->mylocaltime($timestamp, true); $search = array("s","i","H","d","m","Y","y", "z","I"); $replace = array(sprintf("%02d",$dateArr["tm_sec"]), sprintf("%02d",$dateArr["tm_min"]), sprintf("%02d",$dateArr["tm_hour"]), sprintf("%02d",$dateArr["tm_mday"]), sprintf("%02d",$dateArr["tm_mon"]+1), sprintf("%02d",$dateArr["tm_year"]+1900), sprintf("%02d",$dateArr["tm_year"] - (floor($dateArr["tm_year"] / 100) * 100)), $dateArr["tm_yday"], $dateArr["tm_isdst"]); return str_replace($search, $replace, $format); } // enjoyPEAR offers a Date() and a Date_Calc() class which is capable of handling dates pre 1970 and post 2038. PEAR::Date is part of the standard PHP distribution. Example: require_once 'Date/Date.php'; $oDate =& new Date('1967-09-23 00:00:00'); print $oDate->format('%d/%B/%Y %H.%M.%S'); See also: http://pear.php.net http://docs.akbkhome.com/pearcvs/Date.html