mirror of
https://github.com/php/php-src.git
synced 2025-08-19 08:49:28 +02:00
- 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:
parent
47539d32d0
commit
e226f0f87f
6 changed files with 4968 additions and 4299 deletions
File diff suppressed because it is too large
Load diff
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -488,7 +597,8 @@ 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)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
10
ext/date/tests/bug34087.phpt
Normal file
10
ext/date/tests/bug34087.phpt
Normal 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
|
Loading…
Add table
Add a link
Reference in a new issue