summaryrefslogtreecommitdiff
path: root/ext/date/php_date.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/date/php_date.c')
-rw-r--r--ext/date/php_date.c139
1 files changed, 129 insertions, 10 deletions
diff --git a/ext/date/php_date.c b/ext/date/php_date.c
index 6898b28ecc..31076212fe 100644
--- a/ext/date/php_date.c
+++ b/ext/date/php_date.c
@@ -51,6 +51,7 @@ zend_function_entry date_functions[] = {
#ifdef EXPERIMENTAL_DATE_SUPPORT
/* Advanced Interface */
PHP_FE(date_create, NULL)
+ PHP_FE(date_parse, NULL)
PHP_FE(date_format, NULL)
PHP_FE(date_modify, NULL)
PHP_FE(date_timezone_get, NULL)
@@ -63,6 +64,7 @@ zend_function_entry date_functions[] = {
PHP_FE(timezone_open, NULL)
PHP_FE(timezone_name_get, NULL)
+ PHP_FE(timezone_name_from_abbr, NULL)
PHP_FE(timezone_offset_get, NULL)
PHP_FE(timezone_transistions_get, NULL)
PHP_FE(timezone_identifiers_list, NULL)
@@ -269,6 +271,7 @@ PHP_MINIT_FUNCTION(date)
REGISTER_STRING_CONSTANT("DATE_RFC1036", DATE_FORMAT_RFC1036, CONST_CS | CONST_PERSISTENT);
REGISTER_STRING_CONSTANT("DATE_RFC1123", DATE_FORMAT_RFC1123, CONST_CS | CONST_PERSISTENT);
REGISTER_STRING_CONSTANT("DATE_RFC2822", DATE_FORMAT_RFC2822, CONST_CS | CONST_PERSISTENT);
+ REGISTER_STRING_CONSTANT("DATE_RFC3339", DATE_FORMAT_RFC3339, CONST_CS | CONST_PERSISTENT);
REGISTER_STRING_CONSTANT("DATE_RSS", DATE_FORMAT_RFC1123, CONST_CS | CONST_PERSISTENT);
REGISTER_STRING_CONSTANT("DATE_W3C", DATE_FORMAT_RFC3339, CONST_CS | CONST_PERSISTENT);
@@ -793,14 +796,14 @@ PHPAPI void php_date_set_tzdb(timelib_tzdb *tzdb)
PHPAPI signed long php_parse_date(char *string, signed long *now)
{
timelib_time *parsed_time;
- int error1, error2;
+ int error2;
signed long retval;
- parsed_time = timelib_strtotime(string, strlen(string), &error1, DATE_TIMEZONEDB);
+ parsed_time = timelib_strtotime(string, strlen(string), NULL, DATE_TIMEZONEDB);
timelib_update_ts(parsed_time, NULL);
retval = timelib_date_to_int(parsed_time, &error2);
timelib_time_dtor(parsed_time);
- if (error1 || error2) {
+ if (error2) {
return -1;
}
return retval;
@@ -808,12 +811,13 @@ PHPAPI signed long php_parse_date(char *string, signed long *now)
/* }}} */
-/* {{{ proto int strtotime(string time, int now)
+/* {{{ proto int strtotime(string time [, int now ])
Convert string representation of date and time to a timestamp */
PHP_FUNCTION(strtotime)
{
char *times, *initial_ts;
int time_len, error1, error2;
+ struct timelib_error_container *error;
long preset_ts, ts;
timelib_time *t, *now;
@@ -827,7 +831,7 @@ PHP_FUNCTION(strtotime)
initial_ts = emalloc(25);
snprintf(initial_ts, 24, "@%ld", preset_ts);
- t = timelib_strtotime(initial_ts, strlen(initial_ts), &error1, DATE_TIMEZONEDB); /* we ignore the error here, as this should never fail */
+ t = timelib_strtotime(initial_ts, strlen(initial_ts), NULL, DATE_TIMEZONEDB); /* we ignore the error here, as this should never fail */
timelib_update_ts(t, tzi);
now->tz_info = tzi;
now->zone_type = TIMELIB_ZONETYPE_ID;
@@ -844,7 +848,9 @@ PHP_FUNCTION(strtotime)
RETURN_FALSE;
}
- t = timelib_strtotime(times, time_len, &error1, DATE_TIMEZONEDB);
+ t = timelib_strtotime(times, time_len, &error, DATE_TIMEZONEDB);
+ error1 = error->error_count;
+ timelib_error_container_dtor(error);
timelib_fill_holes(t, now, 0);
timelib_update_ts(t, tzi);
ts = timelib_date_to_int(t, &error2);
@@ -1299,7 +1305,6 @@ PHP_FUNCTION(date_create)
{
php_date_obj *dateobj;
zval *timezone_object = NULL;
- int error;
timelib_time *now;
timelib_tzinfo *tzi;
char *time_str;
@@ -1311,7 +1316,7 @@ PHP_FUNCTION(date_create)
date_instanciate(date_ce_date, return_value TSRMLS_CC);
dateobj = (php_date_obj *) zend_object_store_get_object(return_value TSRMLS_CC);
- dateobj->time = timelib_strtotime(time_str_len ? time_str : "now", time_str_len ? time_str_len : sizeof("now") -1, &error, DATE_TIMEZONEDB);
+ dateobj->time = timelib_strtotime(time_str_len ? time_str : "now", time_str_len ? time_str_len : sizeof("now") -1, NULL, DATE_TIMEZONEDB);
if (timezone_object) {
php_timezone_obj *tzobj;
@@ -1343,6 +1348,101 @@ PHP_FUNCTION(date_create)
timelib_time_dtor(now);
}
+PHP_FUNCTION(date_parse)
+{
+ char *date;
+ int date_len, i;
+ struct timelib_error_container *error;
+ timelib_time *parsed_time;
+ zval *element;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &date, &date_len) == FAILURE) {
+ RETURN_FALSE;
+ }
+
+ parsed_time = timelib_strtotime(date, date_len, &error, DATE_TIMEZONEDB);
+ array_init(return_value);
+#define PHP_DATE_PARSE_DATE_SET_TIME_ELEMENT(name, elem) \
+ if (parsed_time->elem == -1) { \
+ add_assoc_bool(return_value, #name, 0); \
+ } else { \
+ add_assoc_long(return_value, #name, parsed_time->elem); \
+ }
+ PHP_DATE_PARSE_DATE_SET_TIME_ELEMENT(year, y);
+ PHP_DATE_PARSE_DATE_SET_TIME_ELEMENT(month, m);
+ PHP_DATE_PARSE_DATE_SET_TIME_ELEMENT(day, d);
+ PHP_DATE_PARSE_DATE_SET_TIME_ELEMENT(hour, h);
+ PHP_DATE_PARSE_DATE_SET_TIME_ELEMENT(minute, i);
+ PHP_DATE_PARSE_DATE_SET_TIME_ELEMENT(second, s);
+
+ if (parsed_time->f == -1) {
+ add_assoc_bool(return_value, "fraction", 0);
+ } else {
+ add_assoc_double(return_value, "fraction", parsed_time->f);
+ }
+
+ add_assoc_long(return_value, "warning_count", error->warning_count);
+ MAKE_STD_ZVAL(element);
+ array_init(element);
+ for (i = 0; i < error->warning_count; i++) {
+ add_index_string(element, error->warning_messages[i].position, error->warning_messages[i].message, 1);
+ }
+ add_assoc_zval(return_value, "warnings", element);
+
+ add_assoc_long(return_value, "error_count", error->error_count);
+ MAKE_STD_ZVAL(element);
+ array_init(element);
+ for (i = 0; i < error->error_count; i++) {
+ add_index_string(element, error->error_messages[i].position, error->error_messages[i].message, 1);
+ }
+ add_assoc_zval(return_value, "errors", element);
+ timelib_error_container_dtor(error);
+
+ add_assoc_bool(return_value, "is_localtime", parsed_time->is_localtime);
+
+ if (parsed_time->is_localtime) {
+ PHP_DATE_PARSE_DATE_SET_TIME_ELEMENT(zone_type, zone_type);
+ switch (parsed_time->zone_type) {
+ case TIMELIB_ZONETYPE_OFFSET:
+ PHP_DATE_PARSE_DATE_SET_TIME_ELEMENT(zone, z);
+ add_assoc_bool(return_value, "is_dst", parsed_time->dst);
+ break;
+ case TIMELIB_ZONETYPE_ID:
+ if (parsed_time->tz_abbr) {
+ add_assoc_string(return_value, "tz_abbr", parsed_time->tz_abbr, 1);
+ }
+ if (parsed_time->tz_info) {
+ add_assoc_string(return_value, "tz_id", parsed_time->tz_info->name, 1);
+ }
+ break;
+ case TIMELIB_ZONETYPE_ABBR:
+ PHP_DATE_PARSE_DATE_SET_TIME_ELEMENT(zone, z);
+ add_assoc_bool(return_value, "is_dst", parsed_time->dst);
+ add_assoc_string(return_value, "tz_abbr", parsed_time->tz_abbr, 1);
+ break;
+ }
+ }
+ if (parsed_time->have_relative || parsed_time->have_weekday_relative) {
+ MAKE_STD_ZVAL(element);
+ array_init(element);
+ }
+ if (parsed_time->have_relative) {
+ add_assoc_long(element, "year", parsed_time->relative.y);
+ add_assoc_long(element, "month", parsed_time->relative.m);
+ add_assoc_long(element, "day", parsed_time->relative.d);
+ add_assoc_long(element, "hour", parsed_time->relative.h);
+ add_assoc_long(element, "minute", parsed_time->relative.i);
+ add_assoc_long(element, "second", parsed_time->relative.s);
+ }
+ if (parsed_time->have_weekday_relative) {
+ add_assoc_long(element, "weekday", parsed_time->relative.weekday);
+ }
+ if (parsed_time->have_relative || parsed_time->have_weekday_relative) {
+ add_assoc_zval(return_value, "relative", element);
+ }
+ timelib_time_dtor(parsed_time);
+}
+
PHP_FUNCTION(date_format)
{
zval *object;
@@ -1363,7 +1463,6 @@ PHP_FUNCTION(date_modify)
php_date_obj *dateobj;
char *modify;
int modify_len;
- int error;
timelib_time *tmp_time;
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &object, date_ce_date, &modify, &modify_len) == FAILURE) {
@@ -1371,7 +1470,7 @@ PHP_FUNCTION(date_modify)
}
dateobj = (php_date_obj *) zend_object_store_get_object(object TSRMLS_CC);
- tmp_time = timelib_strtotime(modify, modify_len, &error, DATE_TIMEZONEDB);
+ 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;
@@ -1544,6 +1643,26 @@ PHP_FUNCTION(timezone_name_get)
RETURN_STRING(tzobj->tz->name, 1);
}
+PHP_FUNCTION(timezone_name_from_abbr)
+{
+ char *abbr;
+ char *tzname;
+ int abbr_len;
+ long gmtoffset = -1;
+ long isdst = -1;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ll", &abbr, &abbr_len, &gmtoffset, &isdst) == FAILURE) {
+ RETURN_FALSE;
+ }
+ tzname = timelib_timezone_id_from_abbr(abbr, gmtoffset, isdst);
+
+ if (tzname) {
+ RETURN_STRING(tzname, 1);
+ } else {
+ RETURN_FALSE;
+ }
+}
+
PHP_FUNCTION(timezone_offset_get)
{
zval *object, *dateobject;