- Fixed bug #34087 (strtotime() does not work with date format "Y/m/d").

- Make use of YYMAXFILL.
- Added support for using a . as hour/minute/second separator.
This commit is contained in:
Derick Rethans 2005-08-24 13:47:28 +00:00
parent 47539d32d0
commit e226f0f87f
6 changed files with 4968 additions and 4299 deletions

File diff suppressed because it is too large Load diff

View file

@ -812,15 +812,15 @@ monthroman = "I" | "II" | "III" | "IV" | "V" | "VI" | "VII" | "VIII" | "IX" | "X
monthtext = monthfull | monthabbr | monthroman; monthtext = monthfull | monthabbr | monthroman;
/* Time formats */ /* Time formats */
timeshort12 = hour12[:]minutelz space? meridian; timeshort12 = hour12[:.]minutelz space? meridian;
timelong12 = hour12[:]minute[:]secondlz space? meridian; timelong12 = hour12[:.]minute[:.]secondlz space? meridian;
timeshort24 = hour24[:]minute; timeshort24 = hour24[:.]minute;
timelong24 = hour24[:]minute[:]second; timelong24 = hour24[:.]minute[:.]second;
iso8601long = hour24 [:] minute [:] second frac; iso8601long = hour24 [:.] minute [:.] second frac;
/* iso8601shorttz = hour24 [:] minutelz space? (tzcorrection | tz); */ /* iso8601shorttz = hour24 [:] minutelz space? (tzcorrection | tz); */
iso8601normtz = hour24 [:] minute [:] secondlz space? (tzcorrection | tz); iso8601normtz = hour24 [:.] minute [:.] secondlz space? (tzcorrection | tz);
/* iso8601longtz = hour24 [:] minute [:] secondlz frac space? (tzcorrection | tz); */ /* iso8601longtz = hour24 [:] minute [:] secondlz frac space? (tzcorrection | tz); */
gnunocolon = hour24lz minutelz; gnunocolon = hour24lz minutelz;
@ -831,7 +831,7 @@ iso8601nocolon = hour24lz minutelz secondlz;
/* Date formats */ /* Date formats */
americanshort = month "/" day; americanshort = month "/" day;
american = month "/" day "/" year; american = month "/" day "/" year;
iso8601dateslash = year4 "/" monthlz "/" daylz "/"?; iso8601dateslash = year4 "/" month "/" daylz "/"?;
gnudateshort = year "-" month "-" day; gnudateshort = year "-" month "-" day;
iso8601date = year4 "-" monthlz "-" daylz; iso8601date = year4 "-" monthlz "-" daylz;
pointeddate = day "." month "." year; pointeddate = day "." month "." year;
@ -969,7 +969,7 @@ relativetext = (reltextnumber space? reltextunit)+;
TIMELIB_HAVE_TIME(); TIMELIB_HAVE_TIME();
s->time->h = timelib_get_nr((char **) &ptr, 2); s->time->h = timelib_get_nr((char **) &ptr, 2);
s->time->i = timelib_get_nr((char **) &ptr, 2); s->time->i = timelib_get_nr((char **) &ptr, 2);
if (*ptr == ':') { if (*ptr == ':' || *ptr == '.') {
s->time->s = timelib_get_nr((char **) &ptr, 2); s->time->s = timelib_get_nr((char **) &ptr, 2);
if (*ptr == '.') { if (*ptr == '.') {
@ -1050,6 +1050,7 @@ relativetext = (reltextnumber space? reltextunit)+;
americanshort | american americanshort | american
{ {
DEBUG_OUTPUT("americanshort | american");
TIMELIB_INIT; TIMELIB_INIT;
TIMELIB_HAVE_DATE(); TIMELIB_HAVE_DATE();
s->time->m = timelib_get_nr((char **) &ptr, 2); s->time->m = timelib_get_nr((char **) &ptr, 2);
@ -1064,6 +1065,7 @@ relativetext = (reltextnumber space? reltextunit)+;
iso8601date | iso8601dateslash iso8601date | iso8601dateslash
{ {
DEBUG_OUTPUT("iso8601date | iso8601dateslash");
TIMELIB_INIT; TIMELIB_INIT;
TIMELIB_HAVE_DATE(); TIMELIB_HAVE_DATE();
s->time->y = timelib_get_nr((char **) &ptr, 4); s->time->y = timelib_get_nr((char **) &ptr, 4);
@ -1075,6 +1077,7 @@ relativetext = (reltextnumber space? reltextunit)+;
gnudateshort gnudateshort
{ {
DEBUG_OUTPUT("gnudateshort");
TIMELIB_INIT; TIMELIB_INIT;
TIMELIB_HAVE_DATE(); TIMELIB_HAVE_DATE();
s->time->y = timelib_get_nr((char **) &ptr, 4); s->time->y = timelib_get_nr((char **) &ptr, 4);
@ -1087,6 +1090,7 @@ relativetext = (reltextnumber space? reltextunit)+;
datefull datefull
{ {
DEBUG_OUTPUT("datefull");
TIMELIB_INIT; TIMELIB_INIT;
TIMELIB_HAVE_DATE(); TIMELIB_HAVE_DATE();
s->time->d = timelib_get_nr((char **) &ptr, 2); s->time->d = timelib_get_nr((char **) &ptr, 2);
@ -1099,6 +1103,7 @@ relativetext = (reltextnumber space? reltextunit)+;
pointeddate pointeddate
{ {
DEBUG_OUTPUT("pointed date");
TIMELIB_INIT; TIMELIB_INIT;
TIMELIB_HAVE_DATE(); TIMELIB_HAVE_DATE();
s->time->d = timelib_get_nr((char **) &ptr, 2); s->time->d = timelib_get_nr((char **) &ptr, 2);
@ -1111,6 +1116,7 @@ relativetext = (reltextnumber space? reltextunit)+;
datenoday datenoday
{ {
DEBUG_OUTPUT("datenoday");
TIMELIB_INIT; TIMELIB_INIT;
TIMELIB_HAVE_DATE(); TIMELIB_HAVE_DATE();
s->time->m = timelib_get_month((char **) &ptr); s->time->m = timelib_get_month((char **) &ptr);
@ -1123,6 +1129,7 @@ relativetext = (reltextnumber space? reltextunit)+;
datenodayrev datenodayrev
{ {
DEBUG_OUTPUT("datenodayrev");
TIMELIB_INIT; TIMELIB_INIT;
TIMELIB_HAVE_DATE(); TIMELIB_HAVE_DATE();
s->time->y = timelib_get_nr((char **) &ptr, 4); s->time->y = timelib_get_nr((char **) &ptr, 4);
@ -1135,6 +1142,7 @@ relativetext = (reltextnumber space? reltextunit)+;
datetextual | datenoyear datetextual | datenoyear
{ {
DEBUG_OUTPUT("datetextual | datenoyear");
TIMELIB_INIT; TIMELIB_INIT;
TIMELIB_HAVE_DATE(); TIMELIB_HAVE_DATE();
s->time->m = timelib_get_month((char **) &ptr); s->time->m = timelib_get_month((char **) &ptr);
@ -1147,6 +1155,7 @@ relativetext = (reltextnumber space? reltextunit)+;
datenoyearrev datenoyearrev
{ {
DEBUG_OUTPUT("datenoyearrev");
TIMELIB_INIT; TIMELIB_INIT;
TIMELIB_HAVE_DATE(); TIMELIB_HAVE_DATE();
s->time->d = timelib_get_nr((char **) &ptr, 2); s->time->d = timelib_get_nr((char **) &ptr, 2);
@ -1157,6 +1166,7 @@ relativetext = (reltextnumber space? reltextunit)+;
datenocolon datenocolon
{ {
DEBUG_OUTPUT("datenocolon");
TIMELIB_INIT; TIMELIB_INIT;
TIMELIB_HAVE_DATE(); TIMELIB_HAVE_DATE();
s->time->y = timelib_get_nr((char **) &ptr, 4); s->time->y = timelib_get_nr((char **) &ptr, 4);
@ -1169,6 +1179,7 @@ relativetext = (reltextnumber space? reltextunit)+;
xmlrpc | xmlrpcnocolon | soap | wddx xmlrpc | xmlrpcnocolon | soap | wddx
{ {
int tz_not_found; int tz_not_found;
DEBUG_OUTPUT("xmlrpc | xmlrpcnocolon | soap | wddx");
TIMELIB_INIT; TIMELIB_INIT;
TIMELIB_HAVE_TIME(); TIMELIB_HAVE_TIME();
TIMELIB_HAVE_DATE(); TIMELIB_HAVE_DATE();
@ -1189,6 +1200,7 @@ relativetext = (reltextnumber space? reltextunit)+;
pgydotd pgydotd
{ {
DEBUG_OUTPUT("pgydotd");
TIMELIB_INIT; TIMELIB_INIT;
TIMELIB_HAVE_DATE(); TIMELIB_HAVE_DATE();
s->time->y = timelib_get_nr((char **) &ptr, 4); s->time->y = timelib_get_nr((char **) &ptr, 4);
@ -1202,7 +1214,7 @@ relativetext = (reltextnumber space? reltextunit)+;
isoweekday isoweekday
{ {
timelib_sll w, d; timelib_sll w, d;
DEBUG_OUTPUT("isoweekday");
TIMELIB_INIT; TIMELIB_INIT;
TIMELIB_HAVE_DATE(); TIMELIB_HAVE_DATE();
TIMELIB_HAVE_RELATIVE(); TIMELIB_HAVE_RELATIVE();
@ -1221,7 +1233,7 @@ relativetext = (reltextnumber space? reltextunit)+;
isoweek isoweek
{ {
timelib_sll w, d; timelib_sll w, d;
DEBUG_OUTPUT("isoweek");
TIMELIB_INIT; TIMELIB_INIT;
TIMELIB_HAVE_DATE(); TIMELIB_HAVE_DATE();
TIMELIB_HAVE_RELATIVE(); TIMELIB_HAVE_RELATIVE();
@ -1239,6 +1251,7 @@ relativetext = (reltextnumber space? reltextunit)+;
pgtextshort pgtextshort
{ {
DEBUG_OUTPUT("pgtextshort");
TIMELIB_INIT; TIMELIB_INIT;
TIMELIB_HAVE_DATE(); TIMELIB_HAVE_DATE();
s->time->m = timelib_get_month((char **) &ptr); s->time->m = timelib_get_month((char **) &ptr);
@ -1251,6 +1264,7 @@ relativetext = (reltextnumber space? reltextunit)+;
pgtextreverse pgtextreverse
{ {
DEBUG_OUTPUT("pgtextreverse");
TIMELIB_INIT; TIMELIB_INIT;
TIMELIB_HAVE_DATE(); TIMELIB_HAVE_DATE();
s->time->y = timelib_get_nr((char **) &ptr, 4); s->time->y = timelib_get_nr((char **) &ptr, 4);
@ -1264,6 +1278,7 @@ relativetext = (reltextnumber space? reltextunit)+;
clf clf
{ {
int tz_not_found; int tz_not_found;
DEBUG_OUTPUT("clf");
TIMELIB_INIT; TIMELIB_INIT;
TIMELIB_HAVE_TIME(); TIMELIB_HAVE_TIME();
TIMELIB_HAVE_DATE(); TIMELIB_HAVE_DATE();
@ -1281,6 +1296,7 @@ relativetext = (reltextnumber space? reltextunit)+;
year4 year4
{ {
DEBUG_OUTPUT("year4");
TIMELIB_INIT; TIMELIB_INIT;
s->time->y = timelib_get_nr((char **) &ptr, 4); s->time->y = timelib_get_nr((char **) &ptr, 4);
TIMELIB_DEINIT; TIMELIB_DEINIT;
@ -1289,6 +1305,7 @@ relativetext = (reltextnumber space? reltextunit)+;
ago ago
{ {
DEBUG_OUTPUT("ago");
TIMELIB_INIT; TIMELIB_INIT;
s->time->relative.y = 0 - s->time->relative.y; s->time->relative.y = 0 - s->time->relative.y;
s->time->relative.m = 0 - s->time->relative.m; s->time->relative.m = 0 - s->time->relative.m;
@ -1304,7 +1321,7 @@ relativetext = (reltextnumber space? reltextunit)+;
relativetext relativetext
{ {
timelib_sll i; timelib_sll i;
DEBUG_OUTPUT("relativetext");
TIMELIB_INIT; TIMELIB_INIT;
TIMELIB_HAVE_RELATIVE(); TIMELIB_HAVE_RELATIVE();
@ -1320,7 +1337,7 @@ relativetext = (reltextnumber space? reltextunit)+;
dayfull dayfull
{ {
const timelib_relunit* relunit; const timelib_relunit* relunit;
DEBUG_OUTPUT("dayfull");
TIMELIB_INIT; TIMELIB_INIT;
TIMELIB_HAVE_RELATIVE(); TIMELIB_HAVE_RELATIVE();
TIMELIB_HAVE_WEEKDAY_RELATIVE(); TIMELIB_HAVE_WEEKDAY_RELATIVE();
@ -1335,12 +1352,14 @@ relativetext = (reltextnumber space? reltextunit)+;
dayabbr dayabbr
{ {
DEBUG_OUTPUT("dayabbr");
goto std; goto std;
} }
tzcorrection | tz tzcorrection | tz
{ {
int tz_not_found; int tz_not_found;
DEBUG_OUTPUT("tzcorrection | tz");
TIMELIB_INIT; TIMELIB_INIT;
s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found); s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found);
s->errors += tz_not_found; s->errors += tz_not_found;
@ -1351,6 +1370,7 @@ relativetext = (reltextnumber space? reltextunit)+;
dateshortwithtimeshort | dateshortwithtimelong | dateshortwithtimelongtz dateshortwithtimeshort | dateshortwithtimelong | dateshortwithtimelongtz
{ {
int tz_not_found; int tz_not_found;
DEBUG_OUTPUT("dateshortwithtimeshort | dateshortwithtimelong | dateshortwithtimelongtz");
TIMELIB_INIT; TIMELIB_INIT;
TIMELIB_HAVE_DATE(); TIMELIB_HAVE_DATE();
s->time->m = timelib_get_month((char **) &ptr); s->time->m = timelib_get_month((char **) &ptr);
@ -1378,7 +1398,7 @@ relativetext = (reltextnumber space? reltextunit)+;
relative relative
{ {
timelib_ull i; timelib_ull i;
DEBUG_OUTPUT("relative");
TIMELIB_INIT; TIMELIB_INIT;
TIMELIB_HAVE_RELATIVE(); TIMELIB_HAVE_RELATIVE();
@ -1419,10 +1439,10 @@ timelib_time* timelib_strtotime(char *s, int *errors)
int t; int t;
memset(&in, 0, sizeof(in)); memset(&in, 0, sizeof(in));
in.str = malloc(strlen(s) + 25); in.str = malloc(strlen(s) + YYMAXFILL);
memset(in.str, 0, strlen(s) + 25); memset(in.str, 0, strlen(s) + YYMAXFILL);
memcpy(in.str, s, strlen(s)); memcpy(in.str, s, strlen(s));
in.lim = in.str + strlen(s) + 25; in.lim = in.str + strlen(s) + YYMAXFILL;
in.cur = in.str; in.cur = in.str;
in.time = timelib_time_ctor(); in.time = timelib_time_ctor();
in.time->y = -1; in.time->y = -1;
@ -1438,7 +1458,9 @@ timelib_time* timelib_strtotime(char *s, int *errors)
do { do {
t = scan(&in); t = scan(&in);
/* printf("%d\n", t); */ #ifdef DEBUG_PARSER
printf("%d\n", t);
#endif
} while(t != EOI); } while(t != EOI);
free(in.str); free(in.str);

View file

@ -812,15 +812,15 @@ monthroman = "I" | "II" | "III" | "IV" | "V" | "VI" | "VII" | "VIII" | "IX" | "X
monthtext = monthfull | monthabbr | monthroman; monthtext = monthfull | monthabbr | monthroman;
/* Time formats */ /* Time formats */
timeshort12 = hour12[:]minutelz space? meridian; timeshort12 = hour12[:.]minutelz space? meridian;
timelong12 = hour12[:]minute[:]secondlz space? meridian; timelong12 = hour12[:.]minute[:.]secondlz space? meridian;
timeshort24 = hour24[:]minute; timeshort24 = hour24[:.]minute;
timelong24 = hour24[:]minute[:]second; timelong24 = hour24[:.]minute[:.]second;
iso8601long = hour24 [:] minute [:] second frac; iso8601long = hour24 [:.] minute [:.] second frac;
/* iso8601shorttz = hour24 [:] minutelz space? (tzcorrection | tz); */ /* iso8601shorttz = hour24 [:] minutelz space? (tzcorrection | tz); */
iso8601normtz = hour24 [:] minute [:] secondlz space? (tzcorrection | tz); iso8601normtz = hour24 [:.] minute [:.] secondlz space? (tzcorrection | tz);
/* iso8601longtz = hour24 [:] minute [:] secondlz frac space? (tzcorrection | tz); */ /* iso8601longtz = hour24 [:] minute [:] secondlz frac space? (tzcorrection | tz); */
gnunocolon = hour24lz minutelz; gnunocolon = hour24lz minutelz;
@ -831,7 +831,7 @@ iso8601nocolon = hour24lz minutelz secondlz;
/* Date formats */ /* Date formats */
americanshort = month "/" day; americanshort = month "/" day;
american = month "/" day "/" year; american = month "/" day "/" year;
iso8601dateslash = year4 "/" monthlz "/" daylz "/"?; iso8601dateslash = year4 "/" month "/" daylz "/"?;
gnudateshort = year "-" month "-" day; gnudateshort = year "-" month "-" day;
iso8601date = year4 "-" monthlz "-" daylz; iso8601date = year4 "-" monthlz "-" daylz;
pointeddate = day "." month "." year; pointeddate = day "." month "." year;
@ -969,7 +969,7 @@ relativetext = (reltextnumber space? reltextunit)+;
TIMELIB_HAVE_TIME(); TIMELIB_HAVE_TIME();
s->time->h = timelib_get_nr((char **) &ptr, 2); s->time->h = timelib_get_nr((char **) &ptr, 2);
s->time->i = timelib_get_nr((char **) &ptr, 2); s->time->i = timelib_get_nr((char **) &ptr, 2);
if (*ptr == ':') { if (*ptr == ':' || *ptr == '.') {
s->time->s = timelib_get_nr((char **) &ptr, 2); s->time->s = timelib_get_nr((char **) &ptr, 2);
if (*ptr == '.') { if (*ptr == '.') {
@ -1050,6 +1050,7 @@ relativetext = (reltextnumber space? reltextunit)+;
americanshort | american americanshort | american
{ {
DEBUG_OUTPUT("americanshort | american");
TIMELIB_INIT; TIMELIB_INIT;
TIMELIB_HAVE_DATE(); TIMELIB_HAVE_DATE();
s->time->m = timelib_get_nr((char **) &ptr, 2); s->time->m = timelib_get_nr((char **) &ptr, 2);
@ -1064,6 +1065,7 @@ relativetext = (reltextnumber space? reltextunit)+;
iso8601date | iso8601dateslash iso8601date | iso8601dateslash
{ {
DEBUG_OUTPUT("iso8601date | iso8601dateslash");
TIMELIB_INIT; TIMELIB_INIT;
TIMELIB_HAVE_DATE(); TIMELIB_HAVE_DATE();
s->time->y = timelib_get_nr((char **) &ptr, 4); s->time->y = timelib_get_nr((char **) &ptr, 4);
@ -1075,6 +1077,7 @@ relativetext = (reltextnumber space? reltextunit)+;
gnudateshort gnudateshort
{ {
DEBUG_OUTPUT("gnudateshort");
TIMELIB_INIT; TIMELIB_INIT;
TIMELIB_HAVE_DATE(); TIMELIB_HAVE_DATE();
s->time->y = timelib_get_nr((char **) &ptr, 4); s->time->y = timelib_get_nr((char **) &ptr, 4);
@ -1087,6 +1090,7 @@ relativetext = (reltextnumber space? reltextunit)+;
datefull datefull
{ {
DEBUG_OUTPUT("datefull");
TIMELIB_INIT; TIMELIB_INIT;
TIMELIB_HAVE_DATE(); TIMELIB_HAVE_DATE();
s->time->d = timelib_get_nr((char **) &ptr, 2); s->time->d = timelib_get_nr((char **) &ptr, 2);
@ -1099,6 +1103,7 @@ relativetext = (reltextnumber space? reltextunit)+;
pointeddate pointeddate
{ {
DEBUG_OUTPUT("pointed date");
TIMELIB_INIT; TIMELIB_INIT;
TIMELIB_HAVE_DATE(); TIMELIB_HAVE_DATE();
s->time->d = timelib_get_nr((char **) &ptr, 2); s->time->d = timelib_get_nr((char **) &ptr, 2);
@ -1111,6 +1116,7 @@ relativetext = (reltextnumber space? reltextunit)+;
datenoday datenoday
{ {
DEBUG_OUTPUT("datenoday");
TIMELIB_INIT; TIMELIB_INIT;
TIMELIB_HAVE_DATE(); TIMELIB_HAVE_DATE();
s->time->m = timelib_get_month((char **) &ptr); s->time->m = timelib_get_month((char **) &ptr);
@ -1123,6 +1129,7 @@ relativetext = (reltextnumber space? reltextunit)+;
datenodayrev datenodayrev
{ {
DEBUG_OUTPUT("datenodayrev");
TIMELIB_INIT; TIMELIB_INIT;
TIMELIB_HAVE_DATE(); TIMELIB_HAVE_DATE();
s->time->y = timelib_get_nr((char **) &ptr, 4); s->time->y = timelib_get_nr((char **) &ptr, 4);
@ -1135,6 +1142,7 @@ relativetext = (reltextnumber space? reltextunit)+;
datetextual | datenoyear datetextual | datenoyear
{ {
DEBUG_OUTPUT("datetextual | datenoyear");
TIMELIB_INIT; TIMELIB_INIT;
TIMELIB_HAVE_DATE(); TIMELIB_HAVE_DATE();
s->time->m = timelib_get_month((char **) &ptr); s->time->m = timelib_get_month((char **) &ptr);
@ -1147,6 +1155,7 @@ relativetext = (reltextnumber space? reltextunit)+;
datenoyearrev datenoyearrev
{ {
DEBUG_OUTPUT("datenoyearrev");
TIMELIB_INIT; TIMELIB_INIT;
TIMELIB_HAVE_DATE(); TIMELIB_HAVE_DATE();
s->time->d = timelib_get_nr((char **) &ptr, 2); s->time->d = timelib_get_nr((char **) &ptr, 2);
@ -1157,6 +1166,7 @@ relativetext = (reltextnumber space? reltextunit)+;
datenocolon datenocolon
{ {
DEBUG_OUTPUT("datenocolon");
TIMELIB_INIT; TIMELIB_INIT;
TIMELIB_HAVE_DATE(); TIMELIB_HAVE_DATE();
s->time->y = timelib_get_nr((char **) &ptr, 4); s->time->y = timelib_get_nr((char **) &ptr, 4);
@ -1169,6 +1179,7 @@ relativetext = (reltextnumber space? reltextunit)+;
xmlrpc | xmlrpcnocolon | soap | wddx xmlrpc | xmlrpcnocolon | soap | wddx
{ {
int tz_not_found; int tz_not_found;
DEBUG_OUTPUT("xmlrpc | xmlrpcnocolon | soap | wddx");
TIMELIB_INIT; TIMELIB_INIT;
TIMELIB_HAVE_TIME(); TIMELIB_HAVE_TIME();
TIMELIB_HAVE_DATE(); TIMELIB_HAVE_DATE();
@ -1189,6 +1200,7 @@ relativetext = (reltextnumber space? reltextunit)+;
pgydotd pgydotd
{ {
DEBUG_OUTPUT("pgydotd");
TIMELIB_INIT; TIMELIB_INIT;
TIMELIB_HAVE_DATE(); TIMELIB_HAVE_DATE();
s->time->y = timelib_get_nr((char **) &ptr, 4); s->time->y = timelib_get_nr((char **) &ptr, 4);
@ -1202,7 +1214,7 @@ relativetext = (reltextnumber space? reltextunit)+;
isoweekday isoweekday
{ {
timelib_sll w, d; timelib_sll w, d;
DEBUG_OUTPUT("isoweekday");
TIMELIB_INIT; TIMELIB_INIT;
TIMELIB_HAVE_DATE(); TIMELIB_HAVE_DATE();
TIMELIB_HAVE_RELATIVE(); TIMELIB_HAVE_RELATIVE();
@ -1221,7 +1233,7 @@ relativetext = (reltextnumber space? reltextunit)+;
isoweek isoweek
{ {
timelib_sll w, d; timelib_sll w, d;
DEBUG_OUTPUT("isoweek");
TIMELIB_INIT; TIMELIB_INIT;
TIMELIB_HAVE_DATE(); TIMELIB_HAVE_DATE();
TIMELIB_HAVE_RELATIVE(); TIMELIB_HAVE_RELATIVE();
@ -1239,6 +1251,7 @@ relativetext = (reltextnumber space? reltextunit)+;
pgtextshort pgtextshort
{ {
DEBUG_OUTPUT("pgtextshort");
TIMELIB_INIT; TIMELIB_INIT;
TIMELIB_HAVE_DATE(); TIMELIB_HAVE_DATE();
s->time->m = timelib_get_month((char **) &ptr); s->time->m = timelib_get_month((char **) &ptr);
@ -1251,6 +1264,7 @@ relativetext = (reltextnumber space? reltextunit)+;
pgtextreverse pgtextreverse
{ {
DEBUG_OUTPUT("pgtextreverse");
TIMELIB_INIT; TIMELIB_INIT;
TIMELIB_HAVE_DATE(); TIMELIB_HAVE_DATE();
s->time->y = timelib_get_nr((char **) &ptr, 4); s->time->y = timelib_get_nr((char **) &ptr, 4);
@ -1264,6 +1278,7 @@ relativetext = (reltextnumber space? reltextunit)+;
clf clf
{ {
int tz_not_found; int tz_not_found;
DEBUG_OUTPUT("clf");
TIMELIB_INIT; TIMELIB_INIT;
TIMELIB_HAVE_TIME(); TIMELIB_HAVE_TIME();
TIMELIB_HAVE_DATE(); TIMELIB_HAVE_DATE();
@ -1281,6 +1296,7 @@ relativetext = (reltextnumber space? reltextunit)+;
year4 year4
{ {
DEBUG_OUTPUT("year4");
TIMELIB_INIT; TIMELIB_INIT;
s->time->y = timelib_get_nr((char **) &ptr, 4); s->time->y = timelib_get_nr((char **) &ptr, 4);
TIMELIB_DEINIT; TIMELIB_DEINIT;
@ -1289,6 +1305,7 @@ relativetext = (reltextnumber space? reltextunit)+;
ago ago
{ {
DEBUG_OUTPUT("ago");
TIMELIB_INIT; TIMELIB_INIT;
s->time->relative.y = 0 - s->time->relative.y; s->time->relative.y = 0 - s->time->relative.y;
s->time->relative.m = 0 - s->time->relative.m; s->time->relative.m = 0 - s->time->relative.m;
@ -1304,7 +1321,7 @@ relativetext = (reltextnumber space? reltextunit)+;
relativetext relativetext
{ {
timelib_sll i; timelib_sll i;
DEBUG_OUTPUT("relativetext");
TIMELIB_INIT; TIMELIB_INIT;
TIMELIB_HAVE_RELATIVE(); TIMELIB_HAVE_RELATIVE();
@ -1320,7 +1337,7 @@ relativetext = (reltextnumber space? reltextunit)+;
dayfull dayfull
{ {
const timelib_relunit* relunit; const timelib_relunit* relunit;
DEBUG_OUTPUT("dayfull");
TIMELIB_INIT; TIMELIB_INIT;
TIMELIB_HAVE_RELATIVE(); TIMELIB_HAVE_RELATIVE();
TIMELIB_HAVE_WEEKDAY_RELATIVE(); TIMELIB_HAVE_WEEKDAY_RELATIVE();
@ -1335,12 +1352,14 @@ relativetext = (reltextnumber space? reltextunit)+;
dayabbr dayabbr
{ {
DEBUG_OUTPUT("dayabbr");
goto std; goto std;
} }
tzcorrection | tz tzcorrection | tz
{ {
int tz_not_found; int tz_not_found;
DEBUG_OUTPUT("tzcorrection | tz");
TIMELIB_INIT; TIMELIB_INIT;
s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found); s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found);
s->errors += tz_not_found; s->errors += tz_not_found;
@ -1351,6 +1370,7 @@ relativetext = (reltextnumber space? reltextunit)+;
dateshortwithtimeshort | dateshortwithtimelong | dateshortwithtimelongtz dateshortwithtimeshort | dateshortwithtimelong | dateshortwithtimelongtz
{ {
int tz_not_found; int tz_not_found;
DEBUG_OUTPUT("dateshortwithtimeshort | dateshortwithtimelong | dateshortwithtimelongtz");
TIMELIB_INIT; TIMELIB_INIT;
TIMELIB_HAVE_DATE(); TIMELIB_HAVE_DATE();
s->time->m = timelib_get_month((char **) &ptr); s->time->m = timelib_get_month((char **) &ptr);
@ -1378,7 +1398,7 @@ relativetext = (reltextnumber space? reltextunit)+;
relative relative
{ {
timelib_ull i; timelib_ull i;
DEBUG_OUTPUT("relative");
TIMELIB_INIT; TIMELIB_INIT;
TIMELIB_HAVE_RELATIVE(); TIMELIB_HAVE_RELATIVE();
@ -1419,10 +1439,10 @@ timelib_time* timelib_strtotime(char *s, int *errors)
int t; int t;
memset(&in, 0, sizeof(in)); memset(&in, 0, sizeof(in));
in.str = malloc(strlen(s) + 25); in.str = malloc(strlen(s) + YYMAXFILL);
memset(in.str, 0, strlen(s) + 25); memset(in.str, 0, strlen(s) + YYMAXFILL);
memcpy(in.str, s, strlen(s)); memcpy(in.str, s, strlen(s));
in.lim = in.str + strlen(s) + 25; in.lim = in.str + strlen(s) + YYMAXFILL;
in.cur = in.str; in.cur = in.str;
in.time = timelib_time_ctor(); in.time = timelib_time_ctor();
in.time->y = -1; in.time->y = -1;
@ -1438,7 +1458,9 @@ timelib_time* timelib_strtotime(char *s, int *errors)
do { do {
t = scan(&in); t = scan(&in);
/* printf("%d\n", t); */ #ifdef DEBUG_PARSER
printf("%d\n", t);
#endif
} while(t != EOI); } while(t != EOI);
free(in.str); free(in.str);

View file

@ -27,6 +27,7 @@
#include "php_date.h" #include "php_date.h"
#include "lib/timelib.h" #include "lib/timelib.h"
#include <time.h> #include <time.h>
#include <unicode/udat.h>
/* {{{ Function table */ /* {{{ Function table */
function_entry date_functions[] = { function_entry date_functions[] = {
@ -50,6 +51,7 @@ function_entry date_functions[] = {
/* Advanced Interface */ /* Advanced Interface */
PHP_FE(date_create, NULL) PHP_FE(date_create, NULL)
PHP_FE(date_format, NULL) PHP_FE(date_format, NULL)
PHP_FE(date_format_locale, NULL)
PHP_FE(date_modify, NULL) PHP_FE(date_modify, NULL)
PHP_FE(date_timezone_get, NULL) PHP_FE(date_timezone_get, NULL)
PHP_FE(date_timezone_set, NULL) PHP_FE(date_timezone_set, NULL)
@ -328,6 +330,9 @@ static char *day_short_names[] = {
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
}; };
static char *am_pm_lower_names[] = { "am", "pm" };
static char *am_pm_upper_names[] = { "AM", "PM" };
static char *english_suffix(timelib_sll number) static char *english_suffix(timelib_sll number)
{ {
if (number >= 10 && number <= 19) { if (number >= 10 && number <= 19) {
@ -344,18 +349,113 @@ static char *english_suffix(timelib_sll number)
/* }}} */ /* }}} */
/* {{{ date_format - (gm)date helper */ /* {{{ date_format - (gm)date helper */
static char *date_format(char *format, int format_len, timelib_time *t, int localtime)
typedef struct {
int day_shortname_lengths[7];
int day_fullname_lengths[7];
int month_shortname_lengths[12];
int month_fullname_lengths[12];
int am_pm_lenghts[2];
char* day_shortname[7];
char* day_fullname[7];
char* month_shortname[12];
char* month_fullname[12];
char* am_pm_name[2];
} php_locale_data;
static const UChar sLongPat [] = { 0x004D, 0x004D, 0x004D, 0x004D, 0x0020,
0x0079, 0x0079, 0x0079, 0x0079 };
#define DATE_LOC_READ(type, var, cor) \
count = udat_countSymbols(fmt, (type)); \
for (i = 0 - (cor); i < count; i++) { \
array[i] = (UChar *) malloc(sizeof(UChar) * 15); \
\
status = U_ZERO_ERROR; \
j = udat_getSymbols(fmt, (type), i, array[i], 15, &status); \
\
tmp->var[i + (cor)] = array[i]; \
}
static php_locale_data* date_get_locale_data(char *locale)
{
php_locale_data *tmp = malloc(sizeof(php_locale_data));
UDateFormat *fmt;
UErrorCode status = 0;
int32_t count, i, j;
UChar *array[15];
UChar *pat = sLongPat;
int32_t len = 9;
fmt = udat_open(UDAT_IGNORE,UDAT_IGNORE, locale, NULL, 0, pat, len, &status);
DATE_LOC_READ(UDAT_WEEKDAYS, day_fullname, -1);
DATE_LOC_READ(UDAT_SHORT_WEEKDAYS, day_shortname, -1);
DATE_LOC_READ(UDAT_MONTHS, month_fullname, 0);
DATE_LOC_READ(UDAT_SHORT_MONTHS, month_shortname, 0);
DATE_LOC_READ(UDAT_AM_PMS, am_pm_name, 0);
udat_close(fmt);
return tmp;
}
static void date_free_locale_data(php_locale_data *data)
{
int i;
for (i = 0; i < 7; ++i) {
free(data->day_shortname[i]);
free(data->day_fullname[i]);
}
for (i = 0; i < 12; ++i) {
free(data->month_shortname[i]);
free(data->month_fullname[i]);
}
free(data->am_pm_name[0]);
free(data->am_pm_name[1]);
free(data);
}
static inline int date_spprintf(char **str, size_t size TSRMLS_DC, const char *format, ...)
{
int c;
va_list ap;
va_start(ap, format);
if (UG(unicode)) {
c = vuspprintf(str, size, format, ap);
} else {
c = vspprintf(str, size, format, ap);
}
va_end(ap);
return c;
}
#define dayname_short(s,l) l ? loc_dat->day_shortname[s] : day_short_names[s]
#define dayname_full(s,l) l ? loc_dat->day_fullname[s] : day_full_names[s]
#define monthname_short(s,l) l ? loc_dat->month_shortname[s] : mon_short_names[s]
#define monthname_full(s,l) l ? loc_dat->month_fullname[s] : mon_full_names[s]
#define am_pm_lower_full(s,l) l ? loc_dat->am_pm_name[s] : am_pm_lower_names[s]
#define am_pm_upper_full(s,l) l ? loc_dat->am_pm_name[s] : am_pm_upper_names[s]
static char *date_format(char *format, int format_len, int *return_len, timelib_time *t, int localtime, int localized)
{ {
smart_str string = {0}; smart_str string = {0};
int i; int i, no_free, length;
char buffer[33]; char *buffer;
timelib_time_offset *offset; timelib_time_offset *offset;
timelib_sll isoweek, isoyear; timelib_sll isoweek, isoyear;
php_locale_data *loc_dat;
if (!format_len) { if (!format_len) {
return estrdup(""); return estrdup("");
} }
loc_dat = date_get_locale_data(UG(default_locale));
if (localtime) { if (localtime) {
if (t->zone_type == TIMELIB_ZONETYPE_ABBR) { if (t->zone_type == TIMELIB_ZONETYPE_ABBR) {
offset = timelib_time_offset_ctor(); offset = timelib_time_offset_ctor();
@ -377,61 +477,61 @@ static char *date_format(char *format, int format_len, timelib_time *t, int loca
offset = timelib_get_time_zone_info(t->sse, t->tz_info); offset = timelib_get_time_zone_info(t->sse, t->tz_info);
} }
} }
buffer[32] = '\0';
timelib_isoweek_from_date(t->y, t->m, t->d, &isoweek, &isoyear); timelib_isoweek_from_date(t->y, t->m, t->d, &isoweek, &isoyear);
for (i = 0; i < format_len; i++) { for (i = 0; i < format_len; i++) {
no_free = 0;
switch (format[i]) { switch (format[i]) {
/* day */ /* day */
case 'd': snprintf(buffer, 32, "%02d", (int) t->d); break; case 'd': length = date_spprintf(&buffer, 32, "%02d", (int) t->d); break;
case 'D': snprintf(buffer, 32, "%s", day_short_names[timelib_day_of_week(t->y, t->m, t->d)]); break; case 'D': length = date_spprintf(&buffer, 32, "%R", localized ? IS_UNICODE : IS_STRING, dayname_short(timelib_day_of_week(t->y, t->m, t->d), localized)); break;
case 'j': snprintf(buffer, 32, "%d", (int) t->d); break; case 'j': length = date_spprintf(&buffer, 32, "%d", (int) t->d); break;
case 'l': snprintf(buffer, 32, "%s", day_full_names[timelib_day_of_week(t->y, t->m, t->d)]); break; case 'l': length = date_spprintf(&buffer, 32, "%R", localized ? IS_UNICODE : IS_STRING, dayname_full(timelib_day_of_week(t->y, t->m, t->d), localized)); break;
case 'S': snprintf(buffer, 32, "%s", english_suffix(t->d)); break; case 'S': length = date_spprintf(&buffer, 32, "%s", english_suffix(t->d)); break;
case 'w': snprintf(buffer, 32, "%d", (int) timelib_day_of_week(t->y, t->m, t->d)); break; case 'w': length = date_spprintf(&buffer, 32, "%d", (int) timelib_day_of_week(t->y, t->m, t->d)); break;
case 'z': snprintf(buffer, 32, "%d", (int) timelib_day_of_year(t->y, t->m, t->d)); break; case 'z': length = date_spprintf(&buffer, 32, "%d", (int) timelib_day_of_year(t->y, t->m, t->d)); break;
/* week */ /* week */
case 'W': snprintf(buffer, 32, "%d", (int) isoweek); break; /* iso weeknr */ case 'W': length = date_spprintf(&buffer, 32, "%d", (int) isoweek); break; /* iso weeknr */
case 'o': snprintf(buffer, 32, "%d", (int) isoyear); break; /* iso year */ case 'o': length = date_spprintf(&buffer, 32, "%d", (int) isoyear); break; /* iso year */
/* month */ /* month */
case 'F': snprintf(buffer, 32, "%s", mon_full_names[t->m - 1]); break; case 'F': length = date_spprintf(&buffer, 32, "%R", localized ? IS_UNICODE : IS_STRING, monthname_full(t->m - 1, localized)); break;
case 'm': snprintf(buffer, 32, "%02d", (int) t->m); break; case 'm': length = date_spprintf(&buffer, 32, "%02d", (int) t->m); break;
case 'M': snprintf(buffer, 32, "%s", mon_short_names[t->m - 1]); break; case 'M': length = date_spprintf(&buffer, 32, "%R", localized ? IS_UNICODE : IS_STRING, monthname_short(t->m - 1, localized)); break;
case 'n': snprintf(buffer, 32, "%d", (int) t->m); break; case 'n': length = date_spprintf(&buffer, 32, "%d", (int) t->m); break;
case 't': snprintf(buffer, 32, "%d", (int) timelib_days_in_month(t->y, t->m)); break; case 't': length = date_spprintf(&buffer, 32, "%d", (int) timelib_days_in_month(t->y, t->m)); break;
/* year */ /* year */
case 'L': snprintf(buffer, 32, "%d", timelib_is_leap((int) t->y)); break; case 'L': length = date_spprintf(&buffer, 32, "%d", timelib_is_leap((int) t->y)); break;
case 'y': snprintf(buffer, 32, "%02d", (int) t->y % 100); break; case 'y': length = date_spprintf(&buffer, 32, "%02d", (int) t->y % 100); break;
case 'Y': snprintf(buffer, 32, "%04d", (int) t->y); break; case 'Y': length = date_spprintf(&buffer, 32, "%04d", (int) t->y); break;
/* time */ /* time */
case 'a': snprintf(buffer, 32, "%s", t->h >= 12 ? "pm" : "am"); break; case 'a': length = date_spprintf(&buffer, 32, "%R", localized ? IS_UNICODE : IS_STRING, am_pm_lower_full(t->h >= 12 ? 1 : 0, localized)); break;
case 'A': snprintf(buffer, 32, "%s", t->h >= 12 ? "PM" : "AM"); break; case 'A': length = date_spprintf(&buffer, 32, "%R", localized ? IS_UNICODE : IS_STRING, am_pm_upper_full(t->h >= 12 ? 1 : 0, localized)); break;
case 'B': snprintf(buffer, 32, "[B unimplemented]"); break; case 'B': length = date_spprintf(&buffer, 32, "[B unimplemented]"); break;
case 'g': snprintf(buffer, 32, "%d", (t->h % 12) ? (int) t->h % 12 : 12); break; case 'g': length = date_spprintf(&buffer, 32, "%d", (t->h % 12) ? (int) t->h % 12 : 12); break;
case 'G': snprintf(buffer, 32, "%d", (int) t->h); break; case 'G': length = date_spprintf(&buffer, 32, "%d", (int) t->h); break;
case 'h': snprintf(buffer, 32, "%02d", (t->h % 12) ? (int) t->h % 12 : 12); break; case 'h': length = date_spprintf(&buffer, 32, "%02d", (t->h % 12) ? (int) t->h % 12 : 12); break;
case 'H': snprintf(buffer, 32, "%02d", (int) t->h); break; case 'H': length = date_spprintf(&buffer, 32, "%02d", (int) t->h); break;
case 'i': snprintf(buffer, 32, "%02d", (int) t->i); break; case 'i': length = date_spprintf(&buffer, 32, "%02d", (int) t->i); break;
case 's': snprintf(buffer, 32, "%02d", (int) t->s); break; case 's': length = date_spprintf(&buffer, 32, "%02d", (int) t->s); break;
/* timezone */ /* timezone */
case 'I': snprintf(buffer, 32, "%d", localtime ? offset->is_dst : 0); break; case 'I': length = date_spprintf(&buffer, 32, "%d", localtime ? offset->is_dst : 0); break;
case 'O': snprintf(buffer, 32, "%c%02d%02d", case 'O': length = date_spprintf(&buffer, 32, "%c%02d%02d",
localtime ? ((offset->offset < 0) ? '-' : '+') : '+', localtime ? ((offset->offset < 0) ? '-' : '+') : '+',
localtime ? abs(offset->offset / 3600) : 0, localtime ? abs(offset->offset / 3600) : 0,
localtime ? abs((offset->offset % 3600) / 60) : 0 localtime ? abs((offset->offset % 3600) / 60) : 0
); );
break; break;
case 'T': snprintf(buffer, 32, "%s", localtime ? offset->abbr : "GMT"); break; case 'T': length = date_spprintf(&buffer, 32, "%s", localtime ? offset->abbr : "GMT"); break;
case 'e': snprintf(buffer, 32, "%s", localtime ? t->tz_info->name : "UTC"); break; case 'e': length = date_spprintf(&buffer, 32, "%s", localtime ? t->tz_info->name : "UTC"); break;
case 'Z': snprintf(buffer, 32, "%d", localtime ? offset->offset : 0); break; case 'Z': length = date_spprintf(&buffer, 32, "%d", localtime ? offset->offset : 0); break;
/* full date/time */ /* full date/time */
case 'c': snprintf(buffer, 32, "%04d-%02d-%02dT%02d:%02d:%02d%c%02d:%02d", case 'c': length = date_spprintf(&buffer, 32, "%04d-%02d-%02dT%02d:%02d:%02d%c%02d:%02d",
(int) t->y, (int) t->m, (int) t->d, (int) t->y, (int) t->m, (int) t->d,
(int) t->h, (int) t->i, (int) t->s, (int) t->h, (int) t->i, (int) t->s,
localtime ? ((offset->offset < 0) ? '-' : '+') : '+', localtime ? ((offset->offset < 0) ? '-' : '+') : '+',
@ -439,7 +539,7 @@ static char *date_format(char *format, int format_len, timelib_time *t, int loca
localtime ? abs((offset->offset % 3600) / 60) : 0 localtime ? abs((offset->offset % 3600) / 60) : 0
); );
break; break;
case 'r': snprintf(buffer, 32, "%3s, %02d %3s %04d %02d:%02d:%02d %c%02d%02d", case 'r': length = date_spprintf(&buffer, 32, "%3s, %02d %3s %04d %02d:%02d:%02d %c%02d%02d",
day_short_names[timelib_day_of_week(t->y, t->m, t->d)], day_short_names[timelib_day_of_week(t->y, t->m, t->d)],
(int) t->d, mon_short_names[t->m - 1], (int) t->d, mon_short_names[t->m - 1],
(int) t->y, (int) t->h, (int) t->i, (int) t->s, (int) t->y, (int) t->h, (int) t->i, (int) t->s,
@ -448,22 +548,31 @@ static char *date_format(char *format, int format_len, timelib_time *t, int loca
localtime ? abs((offset->offset % 3600) / 60) : 0 localtime ? abs((offset->offset % 3600) / 60) : 0
); );
break; break;
case 'U': snprintf(buffer, 32, "%lld", (timelib_sll) t->sse); break; case 'U': length = date_spprintf(&buffer, 32, "%lld", (timelib_sll) t->sse); break;
case '\\': if (i < format_len) i++; buffer[0] = format[i]; buffer[1] = '\0'; break; case '\\': if (i < format_len) i++; length = date_spprintf(&buffer, 32, "%c", format[i]); break;
default: buffer[0] = format[i]; buffer[1] = '\0'; default: length = date_spprintf(&buffer, 32, "%c", format[i]);
break;
}
smart_str_appendl(&string, buffer, length);
if (!no_free) {
efree(buffer);
} }
smart_str_appends(&string, buffer);
buffer[0] = '\0';
} }
smart_str_0(&string); smart_str_0(&string);
date_free_locale_data(loc_dat);
if (localtime) { if (localtime) {
timelib_time_offset_dtor(offset); timelib_time_offset_dtor(offset);
} }
if (UG(unicode)) {
*return_len = string.len / 2;
} else {
*return_len = string.len;
}
return string.c; return string.c;
} }
@ -489,6 +598,7 @@ PHPAPI char *php_format_date(char *format, int format_len, time_t ts, int localt
timelib_time *t; timelib_time *t;
timelib_tzinfo *tzi; timelib_tzinfo *tzi;
char *string; char *string;
int return_len;
t = timelib_time_ctor(); t = timelib_time_ctor();
@ -500,7 +610,7 @@ PHPAPI char *php_format_date(char *format, int format_len, time_t ts, int localt
timelib_unixtime2gmt(t, ts); timelib_unixtime2gmt(t, ts);
} }
string = date_format(format, format_len, t, localtime); string = date_format(format, format_len, &return_len, t, localtime, 0);
if (localtime) { if (localtime) {
timelib_tzinfo_dtor(tzi); timelib_tzinfo_dtor(tzi);
@ -1055,14 +1165,39 @@ PHP_FUNCTION(date_format)
{ {
zval *object; zval *object;
php_date_obj *dateobj; php_date_obj *dateobj;
char *format; char *format, *str;
int format_len; int format_len, length;
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &object, date_ce_date, &format, &format_len) == FAILURE) { if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &object, date_ce_date, &format, &format_len) == FAILURE) {
RETURN_FALSE; RETURN_FALSE;
} }
dateobj = (php_date_obj *) zend_object_store_get_object(object TSRMLS_CC); dateobj = (php_date_obj *) zend_object_store_get_object(object TSRMLS_CC);
RETURN_STRING(date_format(format, format_len, dateobj->time, dateobj->time->is_localtime), 0); str = date_format(format, format_len, &length, dateobj->time, dateobj->time->is_localtime, 0);
if (UG(unicode)) {
RETURN_UNICODEL((UChar*) str, length, 0);
} else {
RETURN_STRINGL(str, length, 0);
}
}
PHP_FUNCTION(date_format_locale)
{
zval *object;
php_date_obj *dateobj;
char *format, *str;
int format_len, length;
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &object, date_ce_date, &format, &format_len) == FAILURE) {
RETURN_FALSE;
}
dateobj = (php_date_obj *) zend_object_store_get_object(object TSRMLS_CC);
str = date_format(format, format_len, &length, dateobj->time, dateobj->time->is_localtime, 1);
if (UG(unicode)) {
RETURN_UNICODEL((UChar*)str, length, 0);
} else {
RETURN_STRINGL(str, length, 0);
}
} }
PHP_FUNCTION(date_modify) PHP_FUNCTION(date_modify)

View file

@ -46,6 +46,7 @@ PHP_FUNCTION(getdate);
/* Advanced Interface */ /* Advanced Interface */
PHP_FUNCTION(date_create); PHP_FUNCTION(date_create);
PHP_FUNCTION(date_format); PHP_FUNCTION(date_format);
PHP_FUNCTION(date_format_locale);
PHP_FUNCTION(date_modify); PHP_FUNCTION(date_modify);
PHP_FUNCTION(date_timezone_get); PHP_FUNCTION(date_timezone_get);
PHP_FUNCTION(date_timezone_set); PHP_FUNCTION(date_timezone_set);

View file

@ -0,0 +1,10 @@
--TEST--
Bug #34087 (strtotime() does not work with date format "Y/m/d")
--FILE--
<?php
echo "Y/m/d: ", strtotime("2005/8/12"), "\n";
echo "Y-m-d: ", strtotime("2005-8-12");
?>
--EXPECT--
Y/m/d: 1123804800
Y-m-d: 1123804800