php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login

Patch Implementation_with_various_bug_fixes for Date/time related Bug #51987

Patch version 2011-01-26 21:41 UTC

Return to Bug #51987 | Download this patch
Patch Revisions:

Developer: jbondc@openmv.com

Index: lib/parse_date.re
===================================================================
--- lib/parse_date.re	(revision 307766)
+++ lib/parse_date.re	(working copy)
@@ -927,7 +927,7 @@
 xmlrpc           = year4 monthlz daylz "T" hour24 ":" minutelz ":" secondlz;
 xmlrpcnocolon    = year4 monthlz daylz 't' hour24 minutelz secondlz;
 wddx             = year4 "-" month "-" day "T" hour24 ":" minute ":" second;
-pgydotd          = year4 "."? dayofyear;
+pgydotd          = year4 [.-]? dayofyear;
 pgtextshort      = monthabbr "-" daylz "-" year;
 pgtextreverse    = year "-" monthabbr "-" daylz;
 mssqltime        = hour12 ":" minutelz ":" secondlz [:.] [0-9]+ meridian;
@@ -1874,13 +1874,15 @@
 			case 'S': /* day suffix, ignored, nor checked */
 				timelib_skip_day_suffix((char **) &ptr);
 				break;
-			case 'z': /* day of year - resets month (0 based) */
+			case 'z': /* day of year - resets month */
 				TIMELIB_CHECK_NUMBER;
 				if ((tmp = timelib_get_nr((char **) &ptr, 3)) == TIMELIB_UNSET) {
 					add_pbf_error(s, "A three digit day-of-year could not be found", string, begin);
 				} else {
 					s->time->m = 1;
-					s->time->d = tmp + 1;
+					s->time->d = 1;
+					s->time->relative.d = tmp;
+					s->time->have_relative = 1;
 				}
 				break;
 
@@ -2084,30 +2086,31 @@
 		add_pbf_error(s, "Data missing", string, ptr);
 	}
 
-	/* clean up a bit */
-	if (s->time->h != TIMELIB_UNSET || s->time->i != TIMELIB_UNSET || s->time->s != TIMELIB_UNSET) {
-		if (s->time->h == TIMELIB_UNSET ) {
-			s->time->h = 0;
-		}
-		if (s->time->i == TIMELIB_UNSET ) {
-			s->time->i = 0;
-		}
-		if (s->time->s == TIMELIB_UNSET ) {
-			s->time->s = 0;
-		}
+	/* assume time units = 0 when not set */
+	if (s->time->h == TIMELIB_UNSET ) {
+		s->time->h = 0;
 	}
+	if (s->time->i == TIMELIB_UNSET ) {
+		s->time->i = 0;
+	}
+	if (s->time->s == TIMELIB_UNSET ) {
+		s->time->s = 0;
+	}
 
-	/* do funky checking whether the parsed time was valid time */
-	if (s->time->h != TIMELIB_UNSET && s->time->i != TIMELIB_UNSET &&
-		s->time->s != TIMELIB_UNSET && 
-		!timelib_valid_time( s->time->h, s->time->i, s->time->s)) {
+	/* check if parsed time is valid */
+	if (!timelib_valid_time(s->time->h, s->time->i, s->time->s)) {
 		add_pbf_warning(s, "The parsed time was invalid", string, ptr);
 	}
+
 	/* do funky checking whether the parsed date was valid date */
 	if (s->time->y != TIMELIB_UNSET && s->time->m != TIMELIB_UNSET &&
-		s->time->d != TIMELIB_UNSET && 
-		!timelib_valid_date( s->time->y, s->time->m, s->time->d)) {
-		add_pbf_warning(s, "The parsed date was invalid", string, ptr);
+		s->time->d != TIMELIB_UNSET) {
+
+		if(s->time->have_relative)
+			timelib_update_ts(s->time, NULL);
+
+		if(!timelib_valid_date(s->time->y, s->time->m, s->time->d))
+			add_pbf_warning(s, "The parsed date was invalid", string, ptr);
 	}
 
 	if (errors) {
Index: lib/tm2unixtime.c
===================================================================
--- lib/tm2unixtime.c	(revision 307766)
+++ lib/tm2unixtime.c	(working copy)
@@ -170,31 +170,34 @@
 
 void timelib_do_rel_normalize(timelib_time *base, timelib_rel_time *rt)
 {
-	do {} while (do_range_limit(0, 60, 60, &rt->s, &rt->i));
-	do {} while (do_range_limit(0, 60, 60, &rt->i, &rt->h));
-	do {} while (do_range_limit(0, 24, 24, &rt->h, &rt->d));
-	do {} while (do_range_limit(0, 12, 12, &rt->m, &rt->y));
+	do_range_limit(0, 60, 60, &rt->s, &rt->i);
+	do_range_limit(0, 60, 60, &rt->i, &rt->h);
+	do_range_limit(0, 24, 24, &rt->h, &rt->d);
+	do_range_limit(0, 12, 12, &rt->m, &rt->y);
 
 	do_range_limit_days_relative(&base->y, &base->m, &rt->y, &rt->m, &rt->d, rt->invert);
-	do {} while (do_range_limit(0, 12, 12, &rt->m, &rt->y));
+	do_range_limit(0, 12, 12, &rt->m, &rt->y);
 }
 
 static void do_normalize(timelib_time* time)
 {
-	do {} while (do_range_limit(0, 60, 60, &time->s, &time->i));
-	do {} while (do_range_limit(0, 60, 60, &time->i, &time->h));
-	do {} while (do_range_limit(0, 24, 24, &time->h, &time->d));
-	do {} while (do_range_limit(1, 13, 12, &time->m, &time->y));
+	do_range_limit(0, 60, 60, &time->s, &time->i);
+	do_range_limit(0, 60, 60, &time->i, &time->h);
+	do_range_limit(0, 24, 24, &time->h, &time->d);
+	do_range_limit(1, 13, 12, &time->m, &time->y);
 
 	do {} while (do_range_limit_days(&time->y, &time->m, &time->d));
-	do {} while (do_range_limit(1, 13, 12, &time->m, &time->y));
+	do_range_limit(1, 13, 12, &time->m, &time->y);
 }
 
 static void do_adjust_relative(timelib_time* time)
 {
+	unsigned char norm = 'f';
+
 	if (time->relative.have_weekday_relative) {
 		do_adjust_for_weekday(time);
 	}
+
 	do_normalize(time);
 
 	if (time->have_relative) {
@@ -205,17 +208,24 @@
 		time->d += time->relative.d;
 		time->m += time->relative.m;
 		time->y += time->relative.y;
+
+		norm = 't';
 	}
+
 	switch (time->relative.first_last_day_of) {
 		case 1: /* first */
 			time->d = 1;
+			norm = 't';
 			break;
 		case 2: /* last */
 			time->d = 0;
 			time->m++;
+			norm = 't';
 			break;
 	}
-	do_normalize(time);
+
+	if(norm == 't')
+		do_normalize(time);
 }
 
 static void do_adjust_special_weekday(timelib_time* time)
@@ -299,8 +309,8 @@
 				time->relative.m = 0;
 				break;
 		}
+		do_normalize(time);
 	}
-	do_normalize(time);
 }
 
 static timelib_sll do_years(timelib_sll year)
Index: php_date.c
===================================================================
--- php_date.c	(revision 307766)
+++ php_date.c	(working copy)
@@ -31,6 +31,8 @@
 #include "lib/timelib.h"
 #include <time.h>
 
+#define TIMELIB_RESET_RELATIVE(t) { t->relative.s = 0;  t->relative.i = 0; t->relative.h = 0; t->relative.d = 0; t->relative.m = 0; t->relative.y = 0; }
+
 #ifdef PHP_WIN32
 static __inline __int64 php_date_llabs( __int64 i ) { return i >= 0? i: -i; }
 #elif defined(__GNUC__) && __GNUC__ < 3
@@ -3085,9 +3087,12 @@
 	dateobj->time->y = y;
 	dateobj->time->m = 1;
 	dateobj->time->d = 1;
+
+	TIMELIB_RESET_RELATIVE(dateobj->time);
+
 	dateobj->time->relative.d = timelib_daynr_from_weeknr(y, w, d);
 	dateobj->time->have_relative = 1;
-	
+
 	timelib_update_ts(dateobj->time, NULL);
 
 	RETURN_ZVAL(object, 1, 0);
Index: tests/bug48187.phpt
===================================================================
--- tests/bug48187.phpt	(revision 307766)
+++ tests/bug48187.phpt	(working copy)
@@ -2,6 +2,7 @@
 Bug #48187 (DateTime::diff() corrupting microtime() result)
 --FILE--
 <?php
+date_default_timezone_set('UTC');
 // two arbitrary dates
 $date1 = new DateTime('2005-07-23');
 $date2 = new DateTime('2006-02-14');
Index: tests/bug51819.phpt
===================================================================
--- tests/bug51819.phpt	(revision 307766)
+++ tests/bug51819.phpt	(working copy)
@@ -2,6 +2,7 @@
 Bug #51819 (Case discrepancy in timezone names cause Uncaught exception and fatal error)
 --FILE--
 <?php
+date_default_timezone_set("UTC");
 $aTzAbbr = timezone_abbreviations_list();
 
 $aTz = array();
Index: tests/bug51866.phpt
===================================================================
--- tests/bug51866.phpt	(revision 307766)
+++ tests/bug51866.phpt	(working copy)
@@ -2,6 +2,7 @@
 Bug #51866 (Lenient parsing with parseFromFormat)
 --FILE--
 <?php
+date_default_timezone_set('UTC');
 $tests = array(
 	array( 'Y-m-d',   '2001-11-29 13:20:01' ),
 	array( 'Y-m-d+',  '2001-11-29 13:20:01' ),
Index: tests/bug51994.phpt
===================================================================
--- tests/bug51994.phpt	(revision 307766)
+++ tests/bug51994.phpt	(working copy)
@@ -16,11 +16,11 @@
   ["day"]=>
   int(3)
   ["hour"]=>
-  bool(false)
+  int(0)
   ["minute"]=>
-  bool(false)
+  int(0)
   ["second"]=>
-  bool(false)
+  int(0)
   ["fraction"]=>
   bool(false)
   ["warning_count"]=>
Index: tests/bug52290.phpt
===================================================================
--- tests/bug52290.phpt	(revision 307766)
+++ tests/bug52290.phpt	(working copy)
@@ -23,5 +23,5 @@
 --EXPECTF--
 string(47) "2005-W52-7 | 2006-01-01 | 00:00:00 | 1136073600"
 string(47) "2005-W52-1 | 2005-12-26 | 00:00:00 | 1135555200"
-string(47) "2007-W40-5 | 2007-10-10 | 00:00:00 | 1191974400"
-string(47) "2007-W40-5 | 2007-10-10 | 20:30:40 | 1192048240"
\ No newline at end of file
+string(47) "2007-W41-3 | 2007-10-10 | 00:00:00 | 1191974400"
+string(47) "2007-W41-3 | 2007-10-10 | 20:30:40 | 1192048240"
\ No newline at end of file
Index: tests/date-lenient.phpt
===================================================================
--- tests/date-lenient.phpt	(revision 307766)
+++ tests/date-lenient.phpt	(working copy)
@@ -19,9 +19,9 @@
     [year] => 2004
     [month] => 6
     [day] => 8
-    [hour] => 
-    [minute] => 
-    [second] => 
+    [hour] => 0
+    [minute] => 0
+    [second] => 0
     [fraction] => 
     [warning_count] => 0
     [warnings] => Array
@@ -41,9 +41,9 @@
     [year] => 2004
     [month] => 6
     [day] => 8
-    [hour] => 
-    [minute] => 
-    [second] => 
+    [hour] => 0
+    [minute] => 0
+    [second] => 0
     [fraction] => 
     [warning_count] => 1
     [warnings] => Array
@@ -63,9 +63,9 @@
     [year] => 2004
     [month] => 6
     [day] => 8
-    [hour] => 
-    [minute] => 
-    [second] => 
+    [hour] => 0
+    [minute] => 0
+    [second] => 0
     [fraction] => 
     [warning_count] => 1
     [warnings] => Array
@@ -85,9 +85,9 @@
     [year] => 2004
     [month] => 6
     [day] => 8
-    [hour] => 
-    [minute] => 
-    [second] => 
+    [hour] => 0
+    [minute] => 0
+    [second] => 0
     [fraction] => 
     [warning_count] => 1
     [warnings] => Array
@@ -107,9 +107,9 @@
     [year] => 2004
     [month] => 6
     [day] => 8
-    [hour] => 
-    [minute] => 
-    [second] => 
+    [hour] => 0
+    [minute] => 0
+    [second] => 0
     [fraction] => 
     [warning_count] => 0
     [warnings] => Array
@@ -128,9 +128,9 @@
     [year] => 2004
     [month] => 6
     [day] => 8
-    [hour] => 
-    [minute] => 
-    [second] => 
+    [hour] => 0
+    [minute] => 0
+    [second] => 0
     [fraction] => 
     [warning_count] => 0
     [warnings] => Array
Index: tests/iso8601.phpt
===================================================================
--- tests/iso8601.phpt	(revision 0)
+++ tests/iso8601.phpt	(revision 0)
@@ -0,0 +1,64 @@
+--TEST--
+Tests for support of ISO 8601-3 (2004-12-01).
+--FILE--
+<?php
+date_default_timezone_set('UTC');
+
+$d = array();
+
+// Calendar date — 12 April 1985
+$d[] = new Datetime('19850412');
+$d[] = new Datetime('1985-04-12');
+
+// Ordinal date — 12 April 1985
+$d[] = new Datetime('1985102');
+$d[] = new Datetime('1985.102');
+$d[] = new Datetime('1985-102');
+
+// Week date — Friday 12 April 1985
+$d[] = new Datetime('1985W155');
+$d[] = new Datetime('1985-W15-5');
+
+// More week dates
+$d[] = new Datetime('2004-W53-6');
+$d[] = new Datetime('2004-W53-7');
+$d[] = new Datetime('2007-W01-1');
+$d[] = new Datetime('2007-W52-7');
+$d[] = new Datetime('2008-W01-1');
+$d[] = new Datetime('2008-W52-7');
+$d[] = new Datetime('2009-W01-1');
+$d[] = new Datetime('2009-W01-4');
+
+// Expanded representations
+// TODO: need setting/flag for leading number of zeros
+// $d1 = new Datetime('+0119850412');
+// $d2 = new Datetime('-00020412');
+// $this->assertSame('+011985-04-12', (string)$d1);
+// $this->assertSame('-0002-04-12', (string)$d2);
+
+// [24:00] on 12 April 1985 is the same as [00:00] on 13 April 1985
+//$d[] = new Datetime('1985-04-12 24:00');
+//$d[] = new Datetime('1985-04-13 00:00');
+//echo (string)$d1 . "\n";
+//echo (string)$d2 . "\n";
+
+foreach($d as $date) {
+	echo $date->format(DateTime::ISO8601), "\n";
+}
+?>
+--EXPECTF--	
+1985-04-12T00:00:00+0000
+1985-04-12T00:00:00+0000
+1985-04-12T00:00:00+0000
+1985-04-12T00:00:00+0000
+1985-04-12T00:00:00+0000
+1985-04-12T00:00:00+0000
+1985-04-12T00:00:00+0000
+2005-01-01T00:00:00+0000
+2005-01-02T00:00:00+0000
+2007-01-01T00:00:00+0000
+2007-12-30T00:00:00+0000
+2007-12-31T00:00:00+0000
+2008-12-28T00:00:00+0000
+2008-12-29T00:00:00+0000
+2009-01-01T00:00:00+0000
\ No newline at end of file
 
PHP Copyright © 2001-2019 The PHP Group
All rights reserved.
Last updated: Tue Mar 26 04:01:27 2019 UTC