Browse Source

- MFH: Fixed weekdays adding/subtracting algorithm.

- MFH: Fixed some ambiguities in the date parser.
- MFH: Fixed bug #45529 (new DateTimeZone() and date_create()->getTimezone()
  behave different).
- MFH: Fixed bug #43452 (strings containing a weekday, or a number plus weekday
  behaved incorrect of the current day-of-week was the same as the one in the
  phrase).
- MFH: Fixed a bug with the YYYY-MM format not resetting the day correctly.
- MFH: Fixed a bug in the DateTime->modify() methods, it would not use the
  advanced relative time strings.
- MFH: Fixed a segfault - simply a forgotten return;
PHP-5.2.1RC1
Derick Rethans 18 years ago
parent
commit
21490362dd
  1. 11
      NEWS
  2. 36553
      ext/date/lib/parse_date.c
  3. 15
      ext/date/lib/parse_date.re
  4. 2
      ext/date/lib/parse_tz.c
  5. 47
      ext/date/lib/tm2unixtime.c
  6. 16
      ext/date/lib/unixtime2tm.c
  7. 9
      ext/date/php_date.c
  8. 71
      ext/date/tests/bug43452.phpt
  9. 4
      ext/date/tests/date_parse_001.phpt
  10. 12
      ext/date/tests/strtotime_basic.phpt

11
NEWS

@ -7,6 +7,17 @@ PHP NEWS
(Tony)
- Fixed bug #46082 (stream_set_blocking() can cause a crash in some
circumstances). (Felipe)
- Fixed bug #45529 (new DateTimeZone() and date_create()->getTimezone() behave
different). (Derick)
- Fixed bug #43452 (strings containing a weekday, or a number plus weekday
behaved incorrect of the current day-of-week was the same as the one in the
phrase).(Derick)
- Fixed weekdays adding/subtracting algorithm. (Derick)
- Fixed some ambiguities in the date parser. (Derick)
- Fixed a bug with the YYYY-MM format not resetting the day correctly. (Derick)
- Fixed a bug in the DateTime->modify() methods, it would not use the advanced
relative time strings. (Derick)
23 Oct 2008, PHP 5.2.7RC2
- Upgraded bundled libzip to 0.9.0. (Pierre)

36553
ext/date/lib/parse_date.c
File diff suppressed because it is too large
View File

15
ext/date/lib/parse_date.re

@ -732,7 +732,7 @@ static long timelib_get_zone(char **ptr, int *dst, timelib_time *t, int *tz_not_
}
#endif
/* If we have a TimeZone identifier to start with, use it */
if (strstr(tz_abbr, "/")) {
if (strstr(tz_abbr, "/") || strcmp(tz_abbr, "UTC") == 0) {
if ((res = timelib_parse_tzfile(tz_abbr, tzdb)) != NULL) {
t->tz_info = res;
t->zone_type = TIMELIB_ZONETYPE_ID;
@ -792,7 +792,7 @@ tzcorrection = [+-] hour24 ":"? minute?;
daysuf = "st" | "nd" | "rd" | "th";
month = "0"? [0-9] | "1"[0-2];
day = ([0-2]?[0-9] | "3"[01]) daysuf?;
day = (([0-2]?[0-9]) | ("3"[01])) daysuf?;
year = [0-9]{1,4};
year2 = [0-9]{2};
year4 = [0-9]{4};
@ -842,11 +842,11 @@ iso8601date2 = year2 "-" monthlz "-" daylz;
gnudateshorter = year4 "-" month;
gnudateshort = year "-" month "-" day;
pointeddate4 = day [.\t-] month [.-] year4;
pointeddate2 = day [.\t-] month [.-] year2;
pointeddate2 = day [.\t] month "." year2;
datefull = day ([ \t.-])* monthtext ([ \t.-])* year;
datenoday = monthtext ([ .\t-])* year4;
datenodayrev = year4 ([ .\t-])* monthtext;
datetextual = monthtext ([ .\t-])* day [,.stndrh\t ]* year;
datetextual = monthtext ([ .\t-])* day [,.stndrh\t ]+ year;
datenoyear = monthtext ([ .\t-])* day [,.stndrh\t ]*;
datenoyearrev = day ([ .\t-])* monthtext;
datenocolon = year4 monthlz daylz;
@ -1125,6 +1125,7 @@ relativetext = reltextnumber space reltextunit;
TIMELIB_HAVE_DATE();
s->time->y = timelib_get_nr((char **) &ptr, 4);
s->time->m = timelib_get_nr((char **) &ptr, 2);
s->time->d = 1;
TIMELIB_PROCESS_YEAR(s->time->y);
TIMELIB_DEINIT;
return TIMELIB_ISO_DATE;
@ -1406,7 +1407,9 @@ relativetext = reltextnumber space reltextunit;
TIMELIB_UNHAVE_TIME();
relunit = timelib_lookup_relunit((char**) &ptr);
s->time->relative.weekday = relunit->multiplier;
s->time->relative.weekday_behavior = 1;
if (s->time->relative.weekday_behavior != 2) {
s->time->relative.weekday_behavior = 1;
}
TIMELIB_DEINIT;
return TIMELIB_WEEKDAY;
@ -1517,7 +1520,7 @@ relativetext = reltextnumber space reltextunit;
while(*ptr) {
i = timelib_get_unsigned_nr((char **) &ptr, 24);
timelib_eat_spaces((char **) &ptr);
timelib_set_relative((char **) &ptr, i, 0, s);
timelib_set_relative((char **) &ptr, i, 1, s);
}
TIMELIB_DEINIT;
return TIMELIB_RELATIVE;

2
ext/date/lib/parse_tz.c

@ -397,7 +397,7 @@ timelib_sll timelib_get_current_offset(timelib_time *t)
switch (t->zone_type) {
case TIMELIB_ZONETYPE_ABBR:
case TIMELIB_ZONETYPE_OFFSET:
return (t->z + t->dst) * 60;
return (t->z + t->dst) * -60;
case TIMELIB_ZONETYPE_ID:
gmt_offset = timelib_get_time_zone_info(t->sse, t->tz_info);

47
ext/date/lib/tm2unixtime.c

@ -136,35 +136,55 @@ static void do_adjust_relative(timelib_time* time)
static void do_adjust_special_weekday(timelib_time* time)
{
timelib_sll current_dow, this_weekday = 0, count;
timelib_sll current_dow, count;
current_dow = timelib_day_of_week(time->y, time->m, time->d);
count = time->special.amount;
current_dow = timelib_day_of_week(time->y, time->m, time->d);
if (count == 0) {
/* skip over saturday and sunday */
if (current_dow == 6) {
this_weekday = 2;
time->d += 2;
}
/* skip over sunday */
if (current_dow == 0) {
this_weekday = 1;
time->d += 1;
}
time->d += this_weekday;
return;
} else if (count > 0) {
/* skip over saturday and sunday */
if (current_dow == 5) {
this_weekday = 2;
time->d += 2;
}
/* skip over sunday */
if (current_dow == 6) {
this_weekday = 1;
time->d += 1;
}
} else if (count < 0) {
if (current_dow == 0) {
this_weekday = -1;
/* add increments of 5 weekdays as a week */
time->d += (count / 5) * 7;
/* if current DOW plus the remainder > 5, add two days */
current_dow = timelib_day_of_week(time->y, time->m, time->d);
time->d += (count % 5);
if ((count % 5) + current_dow > 5) {
time->d += 2;
}
} else if (count < 0) {
/* skip over sunday and saturday */
if (current_dow == 1) {
this_weekday = -2;
time->d -= 2;
}
/* skip over satruday */
if (current_dow == 0 ) {
time->d -= 1;
}
/* subtract increments of 5 weekdays as a week */
time->d += (count / 5) * 7;
/* if current DOW minus the remainder < 0, subtract two days */
current_dow = timelib_day_of_week(time->y, time->m, time->d);
time->d += (count % 5);
if ((count % 5) + current_dow < 1) {
time->d -= 2;
}
}
time->d += this_weekday + ((count / 5) * 7) + (count % 5);
}
static void do_adjust_special(timelib_time* time)
@ -178,6 +198,7 @@ static void do_adjust_special(timelib_time* time)
}
do_normalize(time);
memset(&(time->special), 0, sizeof(time->special));
time->have_relative = 0;
}
static timelib_sll do_years(timelib_sll year)

16
ext/date/lib/unixtime2tm.c

@ -76,12 +76,18 @@ void timelib_unixtime2gmt(timelib_time* tm, timelib_sll ts)
*/
while (tmp_days <= 0) {
cur_year--;
DEBUG(printf("tmp_days=%lld, year=%lld\n", tmp_days, cur_year););
if (timelib_is_leap(cur_year)) {
tmp_days += DAYS_PER_LYEAR;
if (tmp_days < -1460970) {
cur_year -= 4000;
DEBUG(printf("tmp_days=%lld, year=%lld\n", tmp_days, cur_year););
tmp_days += 1460970;
} else {
tmp_days += DAYS_PER_YEAR;
cur_year--;
DEBUG(printf("tmp_days=%lld, year=%lld\n", tmp_days, cur_year););
if (timelib_is_leap(cur_year)) {
tmp_days += DAYS_PER_LYEAR;
} else {
tmp_days += DAYS_PER_YEAR;
}
}
}
remainder += SECS_PER_DAY;

9
ext/date/php_date.c

@ -1920,13 +1920,7 @@ PHP_FUNCTION(date_modify)
DATE_CHECK_INITIALIZED(dateobj->time, DateTime);
tmp_time = timelib_strtotime(modify, modify_len, NULL, DATE_TIMEZONEDB);
dateobj->time->relative.y = tmp_time->relative.y;
dateobj->time->relative.m = tmp_time->relative.m;
dateobj->time->relative.d = tmp_time->relative.d;
dateobj->time->relative.h = tmp_time->relative.h;
dateobj->time->relative.i = tmp_time->relative.i;
dateobj->time->relative.s = tmp_time->relative.s;
dateobj->time->relative.weekday = tmp_time->relative.weekday;
memcpy(&dateobj->time->relative, &tmp_time->relative, sizeof(struct timelib_rel_time));
dateobj->time->have_relative = tmp_time->have_relative;
dateobj->time->have_weekday_relative = tmp_time->have_weekday_relative;
dateobj->time->sse_uptodate = 0;
@ -1993,6 +1987,7 @@ PHP_FUNCTION(date_timezone_set)
tzobj = (php_timezone_obj *) zend_object_store_get_object(timezone_object TSRMLS_CC);
if (tzobj->type != TIMELIB_ZONETYPE_ID) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can only do this for zones with ID for now");
return;
}
timelib_set_timezone(dateobj->time, tzobj->tzi.tz);
timelib_unixtime2local(dateobj->time, dateobj->time->sse);

71
ext/date/tests/bug43452.phpt

@ -0,0 +1,71 @@
--TEST--
Bug #43452 ("weekday" is not equivalent to "1 weekday" of the current weekday is "weekday")
--INI--
date.timezone=Europe/Oslo
--FILE--
<?php
// <day> is equivalent to 1 <day> and will *not* forward if the current day
// (November 1st) is the same day of week.
$day = strtotime( "Thursday Nov 2007" );
echo date( DateTime::ISO8601, $day ), "\n";
$day = strtotime( "1 Thursday Nov 2007" );
echo date( DateTime::ISO8601, $day ), "\n";
$day = strtotime( "2 Thursday Nov 2007" );
echo date( DateTime::ISO8601, $day ), "\n";
$day = strtotime( "3 Thursday Nov 2007" );
echo date( DateTime::ISO8601, $day ), "\n\n";
// forward one week, then behaves like above for week days
$day = strtotime( "Thursday Nov 2007" );
echo date( DateTime::ISO8601, $day ), "\n";
$day = strtotime( "+1 week Thursday Nov 2007" );
echo date( DateTime::ISO8601, $day ), "\n";
$day = strtotime( "+2 week Thursday Nov 2007" );
echo date( DateTime::ISO8601, $day ), "\n";
$day = strtotime( "+3 week Thursday Nov 2007" );
echo date( DateTime::ISO8601, $day ), "\n\n";
// First, second, etc skip to the first/second weekday *after* the current day.
// This makes "first thursday" equivalent to "+1 week thursday" - but only
// if the current day-of-week is the one mentioned in the phrase.
$day = strtotime( "Thursday Nov 2007" );
echo date( DateTime::ISO8601, $day ), "\n";
$day = strtotime( "first Thursday Nov 2007" );
echo date( DateTime::ISO8601, $day ), "\n";
$day = strtotime( "second Thursday Nov 2007" );
echo date( DateTime::ISO8601, $day ), "\n";
$day = strtotime( "third Thursday Nov 2007" );
echo date( DateTime::ISO8601, $day ), "\n\n";
// Now the same where the current day-of-week does not match the one in the
// phrase.
$day = strtotime( "Friday Nov 2007" );
echo date( DateTime::ISO8601, $day ), "\n";
$day = strtotime( "first Friday Nov 2007" );
echo date( DateTime::ISO8601, $day ), "\n";
$day = strtotime( "second Friday Nov 2007" );
echo date( DateTime::ISO8601, $day ), "\n";
$day = strtotime( "third Friday Nov 2007" );
echo date( DateTime::ISO8601, $day ), "\n\n";
?>
--EXPECT--
2007-11-01T00:00:00+0100
2007-11-01T00:00:00+0100
2007-11-08T00:00:00+0100
2007-11-15T00:00:00+0100
2007-11-01T00:00:00+0100
2007-11-08T00:00:00+0100
2007-11-15T00:00:00+0100
2007-11-22T00:00:00+0100
2007-11-01T00:00:00+0100
2007-11-08T00:00:00+0100
2007-11-15T00:00:00+0100
2007-11-22T00:00:00+0100
2007-11-02T00:00:00+0100
2007-11-02T00:00:00+0100
2007-11-09T00:00:00+0100
2007-11-16T00:00:00+0100

4
ext/date/tests/date_parse_001.phpt

@ -79,7 +79,7 @@ array(15) {
["month"]=>
int(12)
["day"]=>
bool(false)
int(1)
["hour"]=>
bool(false)
["minute"]=>
@ -171,7 +171,7 @@ array(12) {
["month"]=>
int(3)
["day"]=>
bool(false)
int(1)
["hour"]=>
bool(false)
["minute"]=>

12
ext/date/tests/strtotime_basic.phpt

@ -41,9 +41,9 @@ var_dump(date('Y-m-d', strtotime('second Monday December 2008')));
var_dump(date('Y-m-d', strtotime('third Monday December 2008')));
?>
--EXPECTF--
%string|unicode%(10) "2008-12-01"
%string|unicode%(10) "2008-12-08"
%string|unicode%(10) "2008-12-15"
%string|unicode%(10) "2008-12-08"
%string|unicode%(10) "2008-12-15"
%string|unicode%(10) "2008-12-22"
string(10) "2008-12-01"
string(10) "2008-12-08"
string(10) "2008-12-15"
string(10) "2008-12-08"
string(10) "2008-12-15"
string(10) "2008-12-22"
Loading…
Cancel
Save