php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #32086 [PATCH] strtotime don't work in DST
Submitted: 2005-02-23 22:01 UTC Modified: 2005-06-18 21:27 UTC
Votes:1
Avg. Score:5.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:0 (0.0%)
Same OS:1 (100.0%)
From: marcus at corp dot grupos dot com dot br Assigned: derick (profile)
Status: Closed Package: Date/time related
PHP Version: 5.*, 4.* OS: FreeBSD 4.x
Private report: No CVE-ID: None
 [2005-02-23 22:01 UTC] marcus at corp dot grupos dot com dot br
Description:
------------
If timestamp don't exist, FreeBSD mktime() return -1 is correct. This case occurs when use strtotime and have Daylight Save Time in timezone.

Example:
If DST save 1 hour and begin on 2004/11/02 00:00, timestamp between 00:00 and 01:00 don't exists.

I fix with this patch, but I find that it is not the best skill.

-- begin patch --
--- ext/standard/parsedate.c.orig       Tue Dec 14 15:55:22 2004
+++ ext/standard/parsedate.c    Mon Feb 14 14:43:08 2005
@@ -2211,9 +2211,9 @@
   date.yyHaveTime = 0;
   date.yyHaveZone = 0;

-  if (yyparse ((void *)&date)
-      || date.yyHaveTime > 1 || date.yyHaveZone > 1
-         || date.yyHaveDate > 1 || date.yyHaveDay > 1)
+  if (yyparse ((void *)&date))
+//      || date.yyHaveTime > 1 || date.yyHaveZone > 1
+//       || date.yyHaveDate > 1 || date.yyHaveDay > 1)
     return -1;

   tm.tm_year = ToYear (date.yyYear) - TM_YEAR_ORIGIN + date.yyRelYear;
@@ -2272,7 +2272,28 @@
        }

       if (Start == (time_t) -1)
-       return Start;
+       {
+               tm = tm0;
+               while((Start = mktime(&tm)) == -1 && tm.tm_year > 68 && tm.tm_year < 138)
+               {
+                       if (tm.tm_isdst == 0)
+                       {
+                               tm.tm_isdst = -1;
+                               if (tm.tm_min < 59) {
+                                       tm.tm_min += 1;
+                               } else {
+                                       tm.tm_min = 0;
+                                       if (tm.tm_hour < 23) {
+                                               tm.tm_hour += 1;
+                                       } else {
+                                               tm.tm_hour = 0;
+                                               tm.tm_mday += 1;
+                                       }
+                               }
+                       }
+               }
+               return Start;
+       }
     }

   if (date.yyHaveDay && !date.yyHaveDate)
-- end patch --

Reproduce code:
---------------
<?php
putenv("TZ=America/Sao_Paulo");
echo $i = strtotime("2004-11-01"), "\n";
echo strtotime("+1 day", $i), "\n";
echo $i = strtotime("2005-02-19"), "\n";
echo strtotime("+1 day", $i), "\n";
?>

America/Sao_Paulo DST begin on 2004/11/02 00:00 and terminate on 2005/02/20 00:00

Expected result:
----------------
1099278000
1099364400
1108778400
1108864800

Actual result:
--------------
1099278000
-1
1108778400
1108864800

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2005-04-06 03:10 UTC] marcus at corp dot grupos dot com dot br
Any idea to fix?

Regards
 [2005-06-18 21:27 UTC] derick@php.net
This bug has been fixed in CVS.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.
 
Thank you for the report, and for helping us make PHP better.

Fixed for PHP 5.1.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 12:01:29 2024 UTC