]> granicus.if.org Git - php/commitdiff
- Fixed bug #27780 (strtotime(+1 xxx) returns a wrong date/time)
authorDerick Rethans <derick@php.net>
Thu, 1 Apr 2004 20:35:41 +0000 (20:35 +0000)
committerDerick Rethans <derick@php.net>
Thu, 1 Apr 2004 20:35:41 +0000 (20:35 +0000)
NEWS
ext/standard/parsedate.y
ext/standard/tests/time/bug27780.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index 5ad56d18349f7287185a03566a7f6128ebd1305f..8525709ef7742e5c8c29042b151758fff51cb893 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -8,6 +8,7 @@ PHP 4                                                                      NEWS
 - Fixed bug #27809 (ftp_systype returns null on some ftp servers). (Ilia)
 - Fixed bug #27802 (default number of children to 8 when PHP_FCGI_CHILDREN is
   not defined). (Ilia)
+- Fixed bug #27780 (strtotime(+1 xxx) returns a wrong date/time). (Derick)
 - Fixed bug #27764 (Get return value from a stored procedure not returning any
   result sets). (Frank)
 - Fixed bug #27762 (SCO Openserver doesn't have S_ISSOCK). (Wez)
index 9fa8c79c30d03003d5808790997162d673d39fdc..bacfcd4b8e80ebc0852a001613d823d09c10f58c 100644 (file)
@@ -150,8 +150,8 @@ typedef union _date_ll {
 
 %}
 
-/* This grammar has 14 shift/reduce conflicts. */
-%expect 14
+/* This grammar has 40 shift/reduce conflicts. */
+%expect 40
 %pure_parser
 
 %token tAGO tDAY tDAY_UNIT tDAYZONE tDST tHOUR_UNIT tID
@@ -192,12 +192,26 @@ time      : tUNUMBER tMERIDIAN {
            ((struct date_yy *)parm)->yyMinutes = 0;
            ((struct date_yy *)parm)->yySeconds = 0;
            ((struct date_yy *)parm)->yyMeridian = $2;
+#ifdef PHP_DEBUG_PARSE_DATE_PARSER
+               printf("[U M]\n");
+#endif
        }
        | tUNUMBER ':' tUNUMBER o_merid {
            ((struct date_yy *)parm)->yyHour = $1;
            ((struct date_yy *)parm)->yyMinutes = $3;
            ((struct date_yy *)parm)->yySeconds = 0;
            ((struct date_yy *)parm)->yyMeridian = $4;
+#ifdef PHP_DEBUG_PARSE_DATE_PARSER
+               printf("[U:U M]\n");
+#endif
+       }
+       | tUNUMBER ':' tUNUMBER rel {
+           ((struct date_yy *)parm)->yyHour = $1;
+           ((struct date_yy *)parm)->yyMinutes = $3;
+           ((struct date_yy *)parm)->yyMeridian = MER24;
+#ifdef PHP_DEBUG_PARSE_DATE_PARSER
+               printf("[U:U rel]\n");
+#endif
        }
        | tUNUMBER ':' tUNUMBER tSNUMBER {
            ((struct date_yy *)parm)->yyHour = $1;
@@ -207,12 +221,27 @@ time      : tUNUMBER tMERIDIAN {
            ((struct date_yy *)parm)->yyTimezone = ($4 < 0
                          ? -$4 % 100 + (-$4 / 100) * 60
                          : - ($4 % 100 + ($4 / 100) * 60));
+#ifdef PHP_DEBUG_PARSE_DATE_PARSER
+               printf("[U:U S]\n");
+#endif
        }
        | tUNUMBER ':' tUNUMBER ':' tUNUMBER o_merid {
            ((struct date_yy *)parm)->yyHour = $1;
            ((struct date_yy *)parm)->yyMinutes = $3;
            ((struct date_yy *)parm)->yySeconds = $5;
            ((struct date_yy *)parm)->yyMeridian = $6;
+#ifdef PHP_DEBUG_PARSE_DATE_PARSER
+               printf("[U:U:U M]\n");
+#endif
+       }
+       | tUNUMBER ':' tUNUMBER ':' tUNUMBER rel {
+           /* ISO 8601 format.  hh:mm:ss[+-][0-9]{2}([0-9]{2})?.  */
+           ((struct date_yy *)parm)->yyHour = $1;
+           ((struct date_yy *)parm)->yyMinutes = $3;
+           ((struct date_yy *)parm)->yySeconds = $5;
+#ifdef PHP_DEBUG_PARSE_DATE_PARSER
+               printf("[U:U:U rel]\n");
+#endif
        }
        | tUNUMBER ':' tUNUMBER ':' tUNUMBER tSNUMBER {
            /* ISO 8601 format.  hh:mm:ss[+-][0-9]{2}([0-9]{2})?.  */
@@ -227,6 +256,9 @@ time        : tUNUMBER tMERIDIAN {
                } else {
                        ((struct date_yy *)parm)->yyTimezone =  -$6 * 60;
                }
+#ifdef PHP_DEBUG_PARSE_DATE_PARSER
+               printf("[U:U:U S]\n");
+#endif
        }
        ;
 
@@ -867,6 +899,9 @@ yylex (YYSTYPE *lvalp, void *parm)
              date->yyInput--;
            }
          }
+#ifdef PHP_DEBUG_PARSE_DATE_PARSER
+         printf ("T: %s\n", sign ? "tS" : "tU");
+#endif
          return sign ? tSNUMBER : tUNUMBER;
        }
       if (ISALPHA (c))
@@ -876,16 +911,27 @@ yylex (YYSTYPE *lvalp, void *parm)
              *p++ = c;
          *p = '\0';
          date->yyInput--;
+#ifdef PHP_DEBUG_PARSE_DATE_PARSER
+         printf ("T: LW\n");
+#endif
          return LookupWord (lvalp, buff);
        }
-      if (c != '(')
+      if (c != '(') {
+#ifdef PHP_DEBUG_PARSE_DATE_PARSER
+       printf ("T: %c\n", *date->yyInput);
+#endif
        return *date->yyInput++;
+         }
       Count = 0;
       do
        {
          c = *date->yyInput++;
-         if (c == '\0')
+         if (c == '\0') {
+#ifdef PHP_DEBUG_PARSE_DATE_PARSER
+       printf ("T: %c\n", c);
+#endif
            return c;
+         }
          if (c == '(')
            Count++;
          else if (c == ')')
diff --git a/ext/standard/tests/time/bug27780.phpt b/ext/standard/tests/time/bug27780.phpt
new file mode 100644 (file)
index 0000000..1c10340
--- /dev/null
@@ -0,0 +1,113 @@
+--TEST--
+Bug #27780 (strtotime(+1 xxx) returns a wrong date/time)
+--FILE--
+<?php
+$timezones = array (
+       "America/Chicago", "Europe/Amsterdam", "Asia/Jerusalem",
+       "Asia/Singapore", "America/Sao_Paulo"
+);
+
+$timestrings = array (
+       "2004-04-07 00:00:00 -2 months +7 days +23 hours +59 minutes +59 seconds",
+       "2004-04-07 00:00:00 -2 months +7 days +23 hours +59 minutes +60 seconds",
+       "2004-04-07 00:00:00 -2 months +7 days +23 hours +59 minutes +61 seconds",
+       "2004-04-07 00:00:00 -21 days",
+       "2004-04-07 00:00:00 11 days ago",
+       "2004-04-07 00:00:00 -10 day +2 hours",
+       "2004-04-07 00:00:00 -1 day",
+       "2004-04-07 00:00:00",
+       "2004-04-07 00:00:00 +1 hour",
+       "2004-04-07 00:00:00 +2 hour",
+       "2004-04-07 00:00:00 +1 day",
+       "2004-04-07 00:00:00 1 day",
+       "2004-04-07 00:00:00 +21 days",
+);
+
+foreach ($timezones as $timezone) {
+       putenv("TZ=$timezone");
+       echo $timezone, "\n";
+
+       foreach ($timestrings as $timestring) {
+               $time = strtotime($timestring);
+
+               echo $time, strftime(" [%Y-%m-%d %H:%M:%S %Z]", $time), " [$timestring]\n";
+       }
+
+       echo "\n";
+}
+?>
+--EXPECT--
+America/Chicago
+1076824799 [2004-02-14 23:59:59 CST] [2004-04-07 00:00:00 -2 months +7 days +23 hours +59 minutes +59 seconds]
+1076824800 [2004-02-15 00:00:00 CST] [2004-04-07 00:00:00 -2 months +7 days +23 hours +59 minutes +60 seconds]
+1076824801 [2004-02-15 00:00:01 CST] [2004-04-07 00:00:00 -2 months +7 days +23 hours +59 minutes +61 seconds]
+1079503200 [2004-03-17 00:00:00 CST] [2004-04-07 00:00:00 -21 days]
+1080367200 [2004-03-27 00:00:00 CST] [2004-04-07 00:00:00 11 days ago]
+1080460800 [2004-03-28 02:00:00 CST] [2004-04-07 00:00:00 -10 day +2 hours]
+1081227600 [2004-04-06 00:00:00 CDT] [2004-04-07 00:00:00 -1 day]
+1081314000 [2004-04-07 00:00:00 CDT] [2004-04-07 00:00:00]
+1081317600 [2004-04-07 01:00:00 CDT] [2004-04-07 00:00:00 +1 hour]
+1081321200 [2004-04-07 02:00:00 CDT] [2004-04-07 00:00:00 +2 hour]
+1081400400 [2004-04-08 00:00:00 CDT] [2004-04-07 00:00:00 +1 day]
+1081400400 [2004-04-08 00:00:00 CDT] [2004-04-07 00:00:00 1 day]
+1083128400 [2004-04-28 00:00:00 CDT] [2004-04-07 00:00:00 +21 days]
+
+Europe/Amsterdam
+1076799599 [2004-02-14 23:59:59 CET] [2004-04-07 00:00:00 -2 months +7 days +23 hours +59 minutes +59 seconds]
+1076799600 [2004-02-15 00:00:00 CET] [2004-04-07 00:00:00 -2 months +7 days +23 hours +59 minutes +60 seconds]
+1076799601 [2004-02-15 00:00:01 CET] [2004-04-07 00:00:00 -2 months +7 days +23 hours +59 minutes +61 seconds]
+1079478000 [2004-03-17 00:00:00 CET] [2004-04-07 00:00:00 -21 days]
+1080342000 [2004-03-27 00:00:00 CET] [2004-04-07 00:00:00 11 days ago]
+1080435600 [2004-03-28 03:00:00 CEST] [2004-04-07 00:00:00 -10 day +2 hours]
+1081202400 [2004-04-06 00:00:00 CEST] [2004-04-07 00:00:00 -1 day]
+1081288800 [2004-04-07 00:00:00 CEST] [2004-04-07 00:00:00]
+1081292400 [2004-04-07 01:00:00 CEST] [2004-04-07 00:00:00 +1 hour]
+1081296000 [2004-04-07 02:00:00 CEST] [2004-04-07 00:00:00 +2 hour]
+1081375200 [2004-04-08 00:00:00 CEST] [2004-04-07 00:00:00 +1 day]
+1081375200 [2004-04-08 00:00:00 CEST] [2004-04-07 00:00:00 1 day]
+1083103200 [2004-04-28 00:00:00 CEST] [2004-04-07 00:00:00 +21 days]
+
+Asia/Jerusalem
+1076795999 [2004-02-14 23:59:59 IST] [2004-04-07 00:00:00 -2 months +7 days +23 hours +59 minutes +59 seconds]
+1076796000 [2004-02-15 00:00:00 IST] [2004-04-07 00:00:00 -2 months +7 days +23 hours +59 minutes +60 seconds]
+1076796001 [2004-02-15 00:00:01 IST] [2004-04-07 00:00:00 -2 months +7 days +23 hours +59 minutes +61 seconds]
+1079474400 [2004-03-17 00:00:00 IST] [2004-04-07 00:00:00 -21 days]
+1080338400 [2004-03-27 00:00:00 IST] [2004-04-07 00:00:00 11 days ago]
+1080432000 [2004-03-28 02:00:00 IST] [2004-04-07 00:00:00 -10 day +2 hours]
+1081202400 [2004-04-06 00:00:00 IST] [2004-04-07 00:00:00 -1 day]
+1081288800 [2004-04-07 00:00:00 IST] [2004-04-07 00:00:00]
+1081292400 [2004-04-07 02:00:00 IDT] [2004-04-07 00:00:00 +1 hour]
+1081292400 [2004-04-07 02:00:00 IDT] [2004-04-07 00:00:00 +2 hour]
+1081371600 [2004-04-08 00:00:00 IDT] [2004-04-07 00:00:00 +1 day]
+1081371600 [2004-04-08 00:00:00 IDT] [2004-04-07 00:00:00 1 day]
+1083099600 [2004-04-28 00:00:00 IDT] [2004-04-07 00:00:00 +21 days]
+
+Asia/Singapore
+1076774399 [2004-02-14 23:59:59 SGT] [2004-04-07 00:00:00 -2 months +7 days +23 hours +59 minutes +59 seconds]
+1076774400 [2004-02-15 00:00:00 SGT] [2004-04-07 00:00:00 -2 months +7 days +23 hours +59 minutes +60 seconds]
+1076774401 [2004-02-15 00:00:01 SGT] [2004-04-07 00:00:00 -2 months +7 days +23 hours +59 minutes +61 seconds]
+1079452800 [2004-03-17 00:00:00 SGT] [2004-04-07 00:00:00 -21 days]
+1080316800 [2004-03-27 00:00:00 SGT] [2004-04-07 00:00:00 11 days ago]
+1080410400 [2004-03-28 02:00:00 SGT] [2004-04-07 00:00:00 -10 day +2 hours]
+1081180800 [2004-04-06 00:00:00 SGT] [2004-04-07 00:00:00 -1 day]
+1081267200 [2004-04-07 00:00:00 SGT] [2004-04-07 00:00:00]
+1081270800 [2004-04-07 01:00:00 SGT] [2004-04-07 00:00:00 +1 hour]
+1081274400 [2004-04-07 02:00:00 SGT] [2004-04-07 00:00:00 +2 hour]
+1081353600 [2004-04-08 00:00:00 SGT] [2004-04-07 00:00:00 +1 day]
+1081353600 [2004-04-08 00:00:00 SGT] [2004-04-07 00:00:00 1 day]
+1083081600 [2004-04-28 00:00:00 SGT] [2004-04-07 00:00:00 +21 days]
+
+America/Sao_Paulo
+1076810399 [2004-02-14 23:59:59 BRST] [2004-04-07 00:00:00 -2 months +7 days +23 hours +59 minutes +59 seconds]
+1076810400 [2004-02-14 23:00:00 BRT] [2004-04-07 00:00:00 -2 months +7 days +23 hours +59 minutes +60 seconds]
+1076810401 [2004-02-14 23:00:01 BRT] [2004-04-07 00:00:00 -2 months +7 days +23 hours +59 minutes +61 seconds]
+1079492400 [2004-03-17 00:00:00 BRT] [2004-04-07 00:00:00 -21 days]
+1080356400 [2004-03-27 00:00:00 BRT] [2004-04-07 00:00:00 11 days ago]
+1080450000 [2004-03-28 02:00:00 BRT] [2004-04-07 00:00:00 -10 day +2 hours]
+1081220400 [2004-04-06 00:00:00 BRT] [2004-04-07 00:00:00 -1 day]
+1081306800 [2004-04-07 00:00:00 BRT] [2004-04-07 00:00:00]
+1081310400 [2004-04-07 01:00:00 BRT] [2004-04-07 00:00:00 +1 hour]
+1081314000 [2004-04-07 02:00:00 BRT] [2004-04-07 00:00:00 +2 hour]
+1081393200 [2004-04-08 00:00:00 BRT] [2004-04-07 00:00:00 +1 day]
+1081393200 [2004-04-08 00:00:00 BRT] [2004-04-07 00:00:00 1 day]
+1083121200 [2004-04-28 00:00:00 BRT] [2004-04-07 00:00:00 +21 days]