mirror of
https://github.com/php/php-src.git
synced 2024-09-23 10:57:26 +00:00
- Added the DatePeriod class/iterator that iterates over a date time object
for a specific number of iterators and applies a DateInterval each time.
This commit is contained in:
parent
93fd16ef4d
commit
b1960e2af3
@ -46,6 +46,13 @@ timelib_rel_time* timelib_rel_time_ctor(void)
|
||||
return t;
|
||||
}
|
||||
|
||||
timelib_rel_time* timelib_rel_time_clone(timelib_rel_time *rel)
|
||||
{
|
||||
timelib_rel_time *tmp = timelib_rel_time_ctor();
|
||||
memcpy(tmp, rel, sizeof(timelib_rel_time));
|
||||
return tmp;
|
||||
}
|
||||
|
||||
void timelib_time_tz_abbr_update(timelib_time* tm, char* tz_abbr)
|
||||
{
|
||||
unsigned int i;
|
||||
|
@ -99,6 +99,7 @@ timelib_tzinfo* timelib_tzinfo_clone(timelib_tzinfo *tz);
|
||||
|
||||
timelib_rel_time* timelib_rel_time_ctor(void);
|
||||
void timelib_rel_time_dtor(timelib_rel_time* t);
|
||||
timelib_rel_time* timelib_rel_time_clone(timelib_rel_time *tz);
|
||||
|
||||
timelib_time* timelib_time_ctor(void);
|
||||
void timelib_time_set_option(timelib_time* tm, int option, void* option_value);
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "ext/standard/php_versioning.h"
|
||||
#include "ext/standard/php_math.h"
|
||||
#include "php_date.h"
|
||||
#include "zend_interfaces.h"
|
||||
#include "lib/timelib.h"
|
||||
#include <time.h>
|
||||
#include <unicode/udat.h>
|
||||
@ -248,8 +249,14 @@ const zend_function_entry date_funcs_interval[] = {
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
const zend_function_entry date_funcs_period[] = {
|
||||
PHP_ME(DatePeriod, __construct, NULL, ZEND_ACC_CTOR|ZEND_ACC_PUBLIC)
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
static char* guess_timezone(const timelib_tzdb *tzdb TSRMLS_DC);
|
||||
static void date_register_classes(TSRMLS_D);
|
||||
static zval * date_instantiate(zend_class_entry *pce, zval *object TSRMLS_DC);
|
||||
/* }}} */
|
||||
|
||||
ZEND_DECLARE_MODULE_GLOBALS(date)
|
||||
@ -278,15 +285,17 @@ PHP_INI_BEGIN()
|
||||
PHP_INI_END()
|
||||
/* }}} */
|
||||
|
||||
zend_class_entry *date_ce_date, *date_ce_timezone, *date_ce_interval;
|
||||
zend_class_entry *date_ce_date, *date_ce_timezone, *date_ce_interval, *date_ce_period;
|
||||
|
||||
static zend_object_handlers date_object_handlers_date;
|
||||
static zend_object_handlers date_object_handlers_timezone;
|
||||
static zend_object_handlers date_object_handlers_interval;
|
||||
static zend_object_handlers date_object_handlers_period;
|
||||
|
||||
typedef struct _php_date_obj php_date_obj;
|
||||
typedef struct _php_timezone_obj php_timezone_obj;
|
||||
typedef struct _php_interval_obj php_interval_obj;
|
||||
typedef struct _php_period_obj php_period_obj;
|
||||
|
||||
struct _php_date_obj {
|
||||
zend_object std;
|
||||
@ -317,6 +326,15 @@ struct _php_interval_obj {
|
||||
int initialized;
|
||||
};
|
||||
|
||||
struct _php_period_obj {
|
||||
zend_object std;
|
||||
timelib_time *start;
|
||||
timelib_time *end;
|
||||
timelib_rel_time *interval;
|
||||
int recurrences;
|
||||
int initialized;
|
||||
};
|
||||
|
||||
#define DATE_SET_CONTEXT \
|
||||
zval *object; \
|
||||
object = getThis(); \
|
||||
@ -344,14 +362,17 @@ struct _php_interval_obj {
|
||||
static void date_object_free_storage_date(void *object TSRMLS_DC);
|
||||
static void date_object_free_storage_timezone(void *object TSRMLS_DC);
|
||||
static void date_object_free_storage_interval(void *object TSRMLS_DC);
|
||||
static void date_object_free_storage_period(void *object TSRMLS_DC);
|
||||
|
||||
static zend_object_value date_object_new_date(zend_class_entry *class_type TSRMLS_DC);
|
||||
static zend_object_value date_object_new_timezone(zend_class_entry *class_type TSRMLS_DC);
|
||||
static zend_object_value date_object_new_interval(zend_class_entry *class_type TSRMLS_DC);
|
||||
static zend_object_value date_object_new_period(zend_class_entry *class_type TSRMLS_DC);
|
||||
|
||||
static zend_object_value date_object_clone_date(zval *this_ptr TSRMLS_DC);
|
||||
static zend_object_value date_object_clone_timezone(zval *this_ptr TSRMLS_DC);
|
||||
static zend_object_value date_object_clone_interval(zval *this_ptr TSRMLS_DC);
|
||||
static zend_object_value date_object_clone_period(zval *this_ptr TSRMLS_DC);
|
||||
|
||||
static int date_object_compare_date(zval *d1, zval *d2 TSRMLS_DC);
|
||||
static HashTable *date_object_get_properties(zval *object TSRMLS_DC);
|
||||
@ -1675,9 +1696,161 @@ PHP_FUNCTION(getdate)
|
||||
#define PHP_DATE_TIMEZONE_GROUP_ALL 0x07FF
|
||||
#define PHP_DATE_TIMEZONE_GROUP_ALL_W_BC 0x0FFF
|
||||
|
||||
|
||||
/* define an overloaded iterator structure */
|
||||
typedef struct {
|
||||
zend_object_iterator intern;
|
||||
zval *current;
|
||||
php_period_obj *object;
|
||||
int current_index;
|
||||
} date_period_it;
|
||||
|
||||
/* {{{ date_period_it_invalidate_current */
|
||||
static void date_period_it_invalidate_current(zend_object_iterator *iter TSRMLS_DC)
|
||||
{
|
||||
date_period_it *iterator = (date_period_it *)iter;
|
||||
|
||||
if (iterator->current) {
|
||||
zval_ptr_dtor(&iterator->current);
|
||||
iterator->current = NULL;
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ date_period_it_dtor */
|
||||
static void date_period_it_dtor(zend_object_iterator *iter TSRMLS_DC)
|
||||
{
|
||||
date_period_it *iterator = (date_period_it *)iter;
|
||||
zval *intern = (zval*)iterator->intern.data;
|
||||
|
||||
date_period_it_invalidate_current(iter TSRMLS_CC);
|
||||
|
||||
efree(iterator);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ date_period_it_has_more */
|
||||
static int date_period_it_has_more(zend_object_iterator *iter TSRMLS_DC)
|
||||
{
|
||||
date_period_it *iterator = (date_period_it *)iter;
|
||||
php_period_obj *object = iterator->object;
|
||||
|
||||
return (iterator->current_index < object->recurrences) ? SUCCESS : FAILURE;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ date_period_it_current_data */
|
||||
static void date_period_it_current_data(zend_object_iterator *iter, zval ***data TSRMLS_DC)
|
||||
{
|
||||
date_period_it *iterator = (date_period_it *)iter;
|
||||
php_period_obj *object = iterator->object;
|
||||
timelib_time *it_time = object->start;
|
||||
php_date_obj *newdateobj;
|
||||
|
||||
/* apply modification */
|
||||
it_time->relative.y = object->interval->y;
|
||||
it_time->relative.m = object->interval->m;
|
||||
it_time->relative.d = object->interval->d;
|
||||
it_time->relative.h = object->interval->h;
|
||||
it_time->relative.i = object->interval->i;
|
||||
it_time->relative.s = object->interval->s;
|
||||
it_time->relative.weekday = object->interval->weekday;
|
||||
it_time->have_relative = 1;
|
||||
it_time->sse_uptodate = 0;
|
||||
timelib_update_ts(it_time, NULL);
|
||||
timelib_update_from_sse(it_time);
|
||||
|
||||
/* Create new object */
|
||||
MAKE_STD_ZVAL(iterator->current);
|
||||
date_instantiate(date_ce_date, iterator->current TSRMLS_CC);
|
||||
newdateobj = (php_date_obj *) zend_object_store_get_object(iterator->current TSRMLS_CC);
|
||||
newdateobj->time = timelib_time_ctor();
|
||||
*newdateobj->time = *it_time;
|
||||
if (it_time->tz_abbr) {
|
||||
newdateobj->time->tz_abbr = strdup(it_time->tz_abbr);
|
||||
}
|
||||
if (it_time->tz_info) {
|
||||
newdateobj->time->tz_info = timelib_tzinfo_clone(it_time->tz_info);
|
||||
}
|
||||
|
||||
*data = &iterator->current;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ date_period_it_current_key */
|
||||
static int date_period_it_current_key(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC)
|
||||
{
|
||||
date_period_it *iterator = (date_period_it *)iter;
|
||||
php_period_obj *object = iterator->object;
|
||||
*int_key = iterator->current_index;
|
||||
return HASH_KEY_IS_LONG;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ date_period_it_move_forward */
|
||||
static void date_period_it_move_forward(zend_object_iterator *iter TSRMLS_DC)
|
||||
{
|
||||
date_period_it *iterator = (date_period_it *)iter;
|
||||
php_period_obj *object = iterator->object;
|
||||
|
||||
iterator->current_index++;
|
||||
date_period_it_invalidate_current(iter TSRMLS_CC);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ date_period_it_rewind */
|
||||
static void date_period_it_rewind(zend_object_iterator *iter TSRMLS_DC)
|
||||
{
|
||||
date_period_it *iterator = (date_period_it *)iter;
|
||||
php_period_obj *object = iterator->object;
|
||||
|
||||
iterator->current_index = 0;
|
||||
date_period_it_invalidate_current(iter TSRMLS_CC);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* iterator handler table */
|
||||
zend_object_iterator_funcs date_period_it_funcs = {
|
||||
date_period_it_dtor,
|
||||
date_period_it_has_more,
|
||||
date_period_it_current_data,
|
||||
date_period_it_current_key,
|
||||
date_period_it_move_forward,
|
||||
date_period_it_rewind,
|
||||
date_period_it_invalidate_current
|
||||
};
|
||||
|
||||
|
||||
|
||||
zend_object_iterator *date_object_period_get_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC)
|
||||
{
|
||||
date_period_it *iterator = emalloc(sizeof(date_period_it));
|
||||
php_period_obj *dpobj = (php_period_obj *)zend_object_store_get_object(object TSRMLS_CC);
|
||||
|
||||
if (by_ref) {
|
||||
zend_error(E_ERROR, "An iterator cannot be used with foreach by reference");
|
||||
}
|
||||
|
||||
Z_ADDREF_P(object);
|
||||
iterator->intern.data = (void*) dpobj;
|
||||
iterator->intern.funcs = &date_period_it_funcs;
|
||||
MAKE_STD_ZVAL(iterator->current);
|
||||
iterator->object = dpobj;
|
||||
iterator->current = NULL;
|
||||
|
||||
return (zend_object_iterator*)iterator;
|
||||
}
|
||||
|
||||
static void date_register_classes(TSRMLS_D)
|
||||
{
|
||||
zend_class_entry ce_date, ce_timezone, ce_interval;
|
||||
zend_class_entry ce_date, ce_timezone, ce_interval, ce_period;
|
||||
|
||||
INIT_CLASS_ENTRY(ce_date, "DateTime", date_funcs_date);
|
||||
ce_date.create_object = date_object_new_date;
|
||||
@ -1733,6 +1906,15 @@ static void date_register_classes(TSRMLS_D)
|
||||
date_object_handlers_interval.clone_obj = date_object_clone_interval;
|
||||
date_object_handlers_interval.read_property = date_interval_read_property;
|
||||
date_object_handlers_interval.write_property = date_interval_write_property;
|
||||
|
||||
INIT_CLASS_ENTRY(ce_period, "DatePeriod", date_funcs_period);
|
||||
ce_period.create_object = date_object_new_period;
|
||||
date_ce_period = zend_register_internal_class_ex(&ce_period, NULL, NULL TSRMLS_CC);
|
||||
date_ce_period->get_iterator = date_object_period_get_iterator;
|
||||
date_ce_period->iterator_funcs.funcs = &date_period_it_funcs;
|
||||
zend_class_implements(date_ce_period TSRMLS_CC, 1, zend_ce_traversable);
|
||||
memcpy(&date_object_handlers_period, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
|
||||
date_object_handlers_period.clone_obj = date_object_clone_period;
|
||||
}
|
||||
|
||||
static inline zend_object_value date_object_new_date_ex(zend_class_entry *class_type, php_date_obj **ptr TSRMLS_DC)
|
||||
@ -1952,6 +2134,44 @@ static zend_object_value date_object_clone_interval(zval *this_ptr TSRMLS_DC)
|
||||
return new_ov;
|
||||
}
|
||||
|
||||
static inline zend_object_value date_object_new_period_ex(zend_class_entry *class_type, php_period_obj **ptr TSRMLS_DC)
|
||||
{
|
||||
php_period_obj *intern;
|
||||
zend_object_value retval;
|
||||
zval *tmp;
|
||||
|
||||
intern = emalloc(sizeof(php_period_obj));
|
||||
memset(intern, 0, sizeof(php_period_obj));
|
||||
if (ptr) {
|
||||
*ptr = intern;
|
||||
}
|
||||
|
||||
zend_object_std_init(&intern->std, class_type TSRMLS_CC);
|
||||
zend_hash_copy(intern->std.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
|
||||
|
||||
retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, (zend_objects_free_object_storage_t) date_object_free_storage_period, NULL TSRMLS_CC);
|
||||
retval.handlers = &date_object_handlers_period;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static zend_object_value date_object_new_period(zend_class_entry *class_type TSRMLS_DC)
|
||||
{
|
||||
return date_object_new_period_ex(class_type, NULL TSRMLS_CC);
|
||||
}
|
||||
|
||||
static zend_object_value date_object_clone_period(zval *this_ptr TSRMLS_DC)
|
||||
{
|
||||
php_period_obj *new_obj = NULL;
|
||||
php_period_obj *old_obj = (php_period_obj *) zend_object_store_get_object(this_ptr TSRMLS_CC);
|
||||
zend_object_value new_ov = date_object_new_period_ex(old_obj->std.ce, &new_obj TSRMLS_CC);
|
||||
|
||||
zend_objects_clone_members(&new_obj->std, new_ov, &old_obj->std, Z_OBJ_HANDLE_P(this_ptr) TSRMLS_CC);
|
||||
|
||||
/** FIX ME ADD CLONE STUFF **/
|
||||
return new_ov;
|
||||
}
|
||||
|
||||
static void date_object_free_storage_date(void *object TSRMLS_DC)
|
||||
{
|
||||
php_date_obj *intern = (php_date_obj *)object;
|
||||
@ -1987,6 +2207,29 @@ static void date_object_free_storage_interval(void *object TSRMLS_DC)
|
||||
efree(object);
|
||||
}
|
||||
|
||||
static void date_object_free_storage_period(void *object TSRMLS_DC)
|
||||
{
|
||||
php_period_obj *intern = (php_period_obj *)object;
|
||||
|
||||
if (intern->start) {
|
||||
if (intern->start->tz_info) {
|
||||
timelib_tzinfo_dtor(intern->start->tz_info);
|
||||
}
|
||||
timelib_time_dtor(intern->start);
|
||||
}
|
||||
|
||||
if (intern->end) {
|
||||
if (intern->end->tz_info) {
|
||||
timelib_tzinfo_dtor(intern->end->tz_info);
|
||||
}
|
||||
timelib_time_dtor(intern->end);
|
||||
}
|
||||
|
||||
timelib_rel_time_dtor(intern->interval);
|
||||
zend_object_std_dtor(&intern->std TSRMLS_CC);
|
||||
efree(object);
|
||||
}
|
||||
|
||||
/* Advanced Interface */
|
||||
static zval * date_instantiate(zend_class_entry *pce, zval *object TSRMLS_DC)
|
||||
{
|
||||
@ -2816,119 +3059,6 @@ static int timezone_initialize(timelib_tzinfo **tzi, /*const*/ char *tz TSRMLS_D
|
||||
}
|
||||
}
|
||||
|
||||
static int date_interval_initialize(timelib_rel_time **rt, /*const*/ char *format, int format_length TSRMLS_DC)
|
||||
{
|
||||
timelib_time *b = NULL, *e = NULL;
|
||||
timelib_rel_time *p = NULL;
|
||||
int r = 0;
|
||||
int retval = 0;
|
||||
struct timelib_error_container *errors;
|
||||
|
||||
timelib_strtointerval(format, format_length, &b, &e, &p, &r, &errors);
|
||||
|
||||
if (errors->error_count > 0) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown or bad format (%s)", format);
|
||||
retval = FAILURE;
|
||||
} else {
|
||||
*rt = p;
|
||||
retval = SUCCESS;
|
||||
}
|
||||
timelib_error_container_dtor(errors);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* {{{ date_interval_read_property */
|
||||
zval *date_interval_read_property(zval *object, zval *member, int type TSRMLS_DC)
|
||||
{
|
||||
php_interval_obj *obj;
|
||||
zval *retval;
|
||||
zval tmp_member;
|
||||
timelib_sll value = -1;
|
||||
|
||||
if (member->type != IS_STRING) {
|
||||
tmp_member = *member;
|
||||
zval_copy_ctor(&tmp_member);
|
||||
convert_to_string(&tmp_member);
|
||||
member = &tmp_member;
|
||||
}
|
||||
|
||||
obj = (php_interval_obj *)zend_objects_get_address(object TSRMLS_CC);
|
||||
|
||||
#define GET_VALUE_FROM_STRUCT(n,m) \
|
||||
if (strcmp(Z_STRVAL_P(member), m) == 0) { \
|
||||
value = obj->diff->n; \
|
||||
}
|
||||
GET_VALUE_FROM_STRUCT(y, "y");
|
||||
GET_VALUE_FROM_STRUCT(m, "m");
|
||||
GET_VALUE_FROM_STRUCT(d, "d");
|
||||
GET_VALUE_FROM_STRUCT(h, "h");
|
||||
GET_VALUE_FROM_STRUCT(i, "i");
|
||||
GET_VALUE_FROM_STRUCT(s, "s");
|
||||
GET_VALUE_FROM_STRUCT(invert, "invert");
|
||||
GET_VALUE_FROM_STRUCT(days, "days");
|
||||
|
||||
if (value == -1) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_ERROR, "Unknown property (%s)", Z_STRVAL_P(member));
|
||||
}
|
||||
|
||||
ALLOC_INIT_ZVAL(retval);
|
||||
ZVAL_LONG(retval, value);
|
||||
|
||||
if (member == &tmp_member) {
|
||||
zval_dtor(member);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ date_interval_write_property */
|
||||
void date_interval_write_property(zval *object, zval *member, zval *value TSRMLS_DC)
|
||||
{
|
||||
php_interval_obj *obj;
|
||||
zval tmp_member, tmp_value;
|
||||
|
||||
if (member->type != IS_STRING) {
|
||||
tmp_member = *member;
|
||||
zval_copy_ctor(&tmp_member);
|
||||
convert_to_string(&tmp_member);
|
||||
member = &tmp_member;
|
||||
}
|
||||
obj = (php_interval_obj *)zend_objects_get_address(object TSRMLS_CC);
|
||||
|
||||
#define SET_VALUE_FROM_STRUCT(n,m) \
|
||||
if (strcmp(Z_STRVAL_P(member), m) == 0) { \
|
||||
if (value->type != IS_LONG) { \
|
||||
tmp_value = *value; \
|
||||
zval_copy_ctor(&tmp_value); \
|
||||
convert_to_long(&tmp_value); \
|
||||
value = &tmp_value; \
|
||||
} \
|
||||
obj->diff->n = Z_LVAL_P(value); \
|
||||
if (value == &tmp_value) { \
|
||||
zval_dtor(value); \
|
||||
} \
|
||||
}
|
||||
|
||||
SET_VALUE_FROM_STRUCT(y, "y");
|
||||
SET_VALUE_FROM_STRUCT(m, "m");
|
||||
SET_VALUE_FROM_STRUCT(d, "d");
|
||||
SET_VALUE_FROM_STRUCT(h, "h");
|
||||
SET_VALUE_FROM_STRUCT(i, "i");
|
||||
SET_VALUE_FROM_STRUCT(s, "s");
|
||||
SET_VALUE_FROM_STRUCT(invert, "invert");
|
||||
|
||||
if (value == -1) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_ERROR, "Unknown property (%s)", Z_STRVAL_P(member));
|
||||
}
|
||||
|
||||
if (member == &tmp_member) {
|
||||
zval_dtor(member);
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ proto DateTimeZone timezone_open(string timezone)
|
||||
Returns new DateTimeZone object
|
||||
*/
|
||||
@ -3162,6 +3292,119 @@ PHP_FUNCTION(timezone_transitions_get)
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static int date_interval_initialize(timelib_rel_time **rt, /*const*/ char *format, int format_length TSRMLS_DC)
|
||||
{
|
||||
timelib_time *b = NULL, *e = NULL;
|
||||
timelib_rel_time *p = NULL;
|
||||
int r = 0;
|
||||
int retval = 0;
|
||||
struct timelib_error_container *errors;
|
||||
|
||||
timelib_strtointerval(format, format_length, &b, &e, &p, &r, &errors);
|
||||
|
||||
if (errors->error_count > 0) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown or bad format (%s)", format);
|
||||
retval = FAILURE;
|
||||
} else {
|
||||
*rt = p;
|
||||
retval = SUCCESS;
|
||||
}
|
||||
timelib_error_container_dtor(errors);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* {{{ date_interval_read_property */
|
||||
zval *date_interval_read_property(zval *object, zval *member, int type TSRMLS_DC)
|
||||
{
|
||||
php_interval_obj *obj;
|
||||
zval *retval;
|
||||
zval tmp_member;
|
||||
timelib_sll value = -1;
|
||||
|
||||
if (member->type != IS_STRING) {
|
||||
tmp_member = *member;
|
||||
zval_copy_ctor(&tmp_member);
|
||||
convert_to_string(&tmp_member);
|
||||
member = &tmp_member;
|
||||
}
|
||||
|
||||
obj = (php_interval_obj *)zend_objects_get_address(object TSRMLS_CC);
|
||||
|
||||
#define GET_VALUE_FROM_STRUCT(n,m) \
|
||||
if (strcmp(Z_STRVAL_P(member), m) == 0) { \
|
||||
value = obj->diff->n; \
|
||||
}
|
||||
GET_VALUE_FROM_STRUCT(y, "y");
|
||||
GET_VALUE_FROM_STRUCT(m, "m");
|
||||
GET_VALUE_FROM_STRUCT(d, "d");
|
||||
GET_VALUE_FROM_STRUCT(h, "h");
|
||||
GET_VALUE_FROM_STRUCT(i, "i");
|
||||
GET_VALUE_FROM_STRUCT(s, "s");
|
||||
GET_VALUE_FROM_STRUCT(invert, "invert");
|
||||
GET_VALUE_FROM_STRUCT(days, "days");
|
||||
|
||||
if (value == -1) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_ERROR, "Unknown property (%s)", Z_STRVAL_P(member));
|
||||
}
|
||||
|
||||
ALLOC_INIT_ZVAL(retval);
|
||||
ZVAL_LONG(retval, value);
|
||||
|
||||
if (member == &tmp_member) {
|
||||
zval_dtor(member);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ date_interval_write_property */
|
||||
void date_interval_write_property(zval *object, zval *member, zval *value TSRMLS_DC)
|
||||
{
|
||||
php_interval_obj *obj;
|
||||
zval tmp_member, tmp_value;
|
||||
|
||||
if (member->type != IS_STRING) {
|
||||
tmp_member = *member;
|
||||
zval_copy_ctor(&tmp_member);
|
||||
convert_to_string(&tmp_member);
|
||||
member = &tmp_member;
|
||||
}
|
||||
obj = (php_interval_obj *)zend_objects_get_address(object TSRMLS_CC);
|
||||
|
||||
#define SET_VALUE_FROM_STRUCT(n,m) \
|
||||
if (strcmp(Z_STRVAL_P(member), m) == 0) { \
|
||||
if (value->type != IS_LONG) { \
|
||||
tmp_value = *value; \
|
||||
zval_copy_ctor(&tmp_value); \
|
||||
convert_to_long(&tmp_value); \
|
||||
value = &tmp_value; \
|
||||
} \
|
||||
obj->diff->n = Z_LVAL_P(value); \
|
||||
if (value == &tmp_value) { \
|
||||
zval_dtor(value); \
|
||||
} \
|
||||
}
|
||||
|
||||
SET_VALUE_FROM_STRUCT(y, "y");
|
||||
SET_VALUE_FROM_STRUCT(m, "m");
|
||||
SET_VALUE_FROM_STRUCT(d, "d");
|
||||
SET_VALUE_FROM_STRUCT(h, "h");
|
||||
SET_VALUE_FROM_STRUCT(i, "i");
|
||||
SET_VALUE_FROM_STRUCT(s, "s");
|
||||
SET_VALUE_FROM_STRUCT(invert, "invert");
|
||||
|
||||
if (value == -1) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_ERROR, "Unknown property (%s)", Z_STRVAL_P(member));
|
||||
}
|
||||
|
||||
if (member == &tmp_member) {
|
||||
zval_dtor(member);
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ proto DateInterval::__construct([string interval_spec])
|
||||
Creates new DateInterval object.
|
||||
*/
|
||||
@ -3261,6 +3504,46 @@ PHP_FUNCTION(date_interval_format)
|
||||
RETURN_STRING(date_interval_format(format, format_len, diobj->diff), 0);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto DatePeriod::__construct(DateTime $start, DateInterval $interval, int recurrences)
|
||||
Creates new DatePeriod object.
|
||||
*/
|
||||
PHP_METHOD(DatePeriod, __construct)
|
||||
{
|
||||
php_period_obj *dpobj;
|
||||
php_date_obj *dateobj;
|
||||
php_interval_obj *intobj;
|
||||
zval *start, *interval;
|
||||
long recurrences;
|
||||
timelib_time *clone;
|
||||
|
||||
php_set_error_handling(EH_THROW, NULL TSRMLS_CC);
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "OOl", &start, date_ce_date, &interval, date_ce_interval, &recurrences) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
dateobj = (php_date_obj *) zend_object_store_get_object(start TSRMLS_CC);
|
||||
intobj = (php_interval_obj *) zend_object_store_get_object(interval TSRMLS_CC);
|
||||
|
||||
clone = timelib_time_ctor();
|
||||
memcpy(clone, dateobj->time, sizeof(timelib_time));
|
||||
if (dateobj->time->tz_abbr) {
|
||||
clone->tz_abbr = strdup(dateobj->time->tz_abbr);
|
||||
}
|
||||
if (dateobj->time->tz_info) {
|
||||
clone->tz_info = timelib_tzinfo_clone(dateobj->time->tz_info);
|
||||
}
|
||||
|
||||
dpobj = zend_object_store_get_object(getThis() TSRMLS_CC);
|
||||
dpobj->interval = timelib_rel_time_clone(intobj->diff);
|
||||
dpobj->start = clone;
|
||||
dpobj->recurrences = recurrences;
|
||||
dpobj->initialized = 1;
|
||||
|
||||
php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static int check_id_allowed(char *id, long what)
|
||||
{
|
||||
if (what & PHP_DATE_TIMEZONE_GROUP_AFRICA && strncasecmp(id, "Africa/", 7) == 0) return 1;
|
||||
|
@ -86,6 +86,8 @@ PHP_METHOD(timezone, abbreviations_list);
|
||||
PHP_METHOD(DateInterval, __construct);
|
||||
PHP_FUNCTION(date_interval_format);
|
||||
|
||||
PHP_METHOD(DatePeriod, __construct);
|
||||
|
||||
/* Options and Configuration */
|
||||
PHP_FUNCTION(date_default_timezone_set);
|
||||
PHP_FUNCTION(date_default_timezone_get);
|
||||
|
Loading…
Reference in New Issue
Block a user