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
|