Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 77 additions & 0 deletions ext/date/php_date.c
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,10 @@ ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_date_interval_construct, 0, 0, 0)
ZEND_ARG_INFO(0, interval_spec)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_date_set_default_format, 0, 0, 1)
ZEND_ARG_INFO(0, format)
ZEND_END_ARG_INFO();
/* }}} */

/* {{{ Function table */
Expand Down Expand Up @@ -432,6 +436,9 @@ const zend_function_entry date_funcs_date[] = {
PHP_ME(DateTime, __construct, arginfo_date_create, ZEND_ACC_CTOR|ZEND_ACC_PUBLIC)
PHP_ME(DateTime, __wakeup, NULL, ZEND_ACC_PUBLIC)
PHP_ME(DateTime, __set_state, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
PHP_ME(DateTime, __toString, NULL, ZEND_ACC_PUBLIC)
PHP_ME(DateTime, setDefaultFormat, arginfo_date_set_default_format, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
PHP_ME(DateTime, getDefaultFormat, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
PHP_ME_MAPPING(createFromFormat, date_create_from_format, arginfo_date_create_from_format, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
PHP_ME_MAPPING(getLastErrors, date_get_last_errors, arginfo_date_get_last_errors, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
PHP_ME_MAPPING(format, date_format, arginfo_date_method_format, 0)
Expand Down Expand Up @@ -1899,6 +1906,12 @@ static void date_register_classes(TSRMLS_D)
REGISTER_DATE_CLASS_CONST_STRING("RSS", DATE_FORMAT_RFC1123);
REGISTER_DATE_CLASS_CONST_STRING("W3C", DATE_FORMAT_RFC3339);

#define REGISTER_DATE_CLASS_PROPERTY_PROTECTED_STRING(const_name, value, access_type ) \
zend_declare_property_string(date_ce_date, const_name, sizeof(const_name)-1, value, access_type)

REGISTER_DATE_CLASS_PROPERTY_PROTECTED_STRING("defaultFormat", DATE_FORMAT_ISO8601,
ZEND_ACC_STATIC|ZEND_ACC_PROTECTED TSRMLS_DC);


INIT_CLASS_ENTRY(ce_timezone, "DateTimeZone", date_funcs_timezone);
ce_timezone.create_object = date_object_new_timezone;
Expand Down Expand Up @@ -2535,6 +2548,70 @@ PHP_METHOD(DateTime, __wakeup)
php_date_initialize_from_hash(&return_value, &dateobj, myht TSRMLS_CC);
}
/* }}} */
/* {{{ proto DateTime::__toString()
*/PHP_METHOD(DateTime, __toString) {
php_date_obj *dateobj;
zval *format;
zval *object = getThis();

char *property = "defaultFormat";
zend_class_entry* ce = 0L;

if (EG(called_scope)) {
ce = EG(called_scope);
} else if (!EG(scope)) {
ce = EG(scope);
}

dateobj = (php_date_obj *) zend_object_store_get_object(object TSRMLS_CC);
DATE_CHECK_INITIALIZED(dateobj->time, DateTime);

format = zend_read_static_property(ce, property, strlen(property), 0);


RETURN_STRING(date_format(Z_STRVAL_P(format), Z_STRLEN_P(format), dateobj->time, dateobj->time->is_localtime),0);
}
/* }}} */

/* {{{ proto DateTime::setDefaultFormat(string format)
*/PHP_METHOD(DateTime, setDefaultFormat) {
zval *object = getThis();
char *property = "defaultFormat";
zend_class_entry* ce = 0L;

char *format;
int format_len;

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &format, &format_len) == FAILURE) {
RETURN_FALSE;
}

if (EG(called_scope)) {
ce = EG(called_scope);
} else if (!EG(scope)) {
ce = EG(scope);
}
zend_update_static_property_stringl(ce, property, strlen(property), format, format_len);
RETURN_TRUE;
}
/* }}} */

/* {{{ proto DateTime::getDefaultFormat()
*/PHP_METHOD(DateTime, getDefaultFormat) {
zval *object = getThis();
char *property = "defaultFormat";
zend_class_entry* ce = 0L;
zval *format;

if (EG(called_scope)) {
ce = EG(called_scope);
} else if (!EG(scope)) {
ce = EG(scope);
}
format = zend_read_static_property(ce, property, strlen(property), 0);
RETURN_STRINGL(Z_STRVAL_P(format), Z_STRLEN_P(format), 1);
}
/* }}} */

/* Helper function used to add an associative array of warnings and errors to a zval */
static void zval_from_error_container(zval *z, timelib_error_container *error)
Expand Down
3 changes: 3 additions & 0 deletions ext/date/php_date.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ PHP_FUNCTION(getdate);
PHP_METHOD(DateTime, __construct);
PHP_METHOD(DateTime, __wakeup);
PHP_METHOD(DateTime, __set_state);
PHP_METHOD(DateTime, __toString);
PHP_METHOD(DateTime, setDefaultFormat);
PHP_METHOD(DateTime, getDefaultFormat);
PHP_FUNCTION(date_create);
PHP_FUNCTION(date_create_from_format);
PHP_FUNCTION(date_parse);
Expand Down
15 changes: 15 additions & 0 deletions ext/date/tests/DateTime_toString.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
--TEST--
DateTime::__toString() -- Inheritance
--CREDITS--
Thomas Rothe <th.rothe@gmail.com>
--FILE--
<?php
date_default_timezone_set("Europe/Berlin");
DateTime::setDefaultFormat('d.m.Y H:i');
$dateTime = DateTime::createFromFormat('Y-m-d H:i:s','2012-06-07 22:18:05');
echo $dateTime . PHP_EOL;
echo Datetime::getDefaultFormat() . PHP_EOL;
?>
--EXPECT--
07.06.2012 22:18
d.m.Y H:i
20 changes: 20 additions & 0 deletions ext/date/tests/DateTime_toString_inheritance.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
--TEST--
DateTime::__toString()
--CREDITS--
Thomas Rothe <th.rothe@gmail.com>
--FILE--
<?php
date_default_timezone_set("Europe/Berlin");
class GermanDate extends Datetime
{
protected static $defaultFormat = 'd.m.Y';
}
$dateTime = new GermanDate("06/07/2012");
echo $dateTime . PHP_EOL;
echo GermanDate::getDefaultFormat() . PHP_EOL;
echo DateTime::getDefaultFormat() . PHP_EOL;
?>
--EXPECT--
07.06.2012
d.m.Y
Y-m-d\TH:i:sO
89 changes: 55 additions & 34 deletions ext/date/tests/DateTime_verify.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -22,133 +22,154 @@ var_dump($constants);
--EXPECTF--
*** Verify DateTime class ***
Verify DateTime class registered OK
object(ReflectionClass)#%d (1) {
object(ReflectionClass)#1 (1) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it's a good idea - what it is testing? Fixed order of values in the hash? Why would we want to test for that? You yourself can see that this leads to a lot of changes each time method is added, why do that? I think %d's should be left alone.

["name"]=>
string(8) "DateTime"
}
..and get names of all its methods
array(18) {
array(21) {
[0]=>
&object(ReflectionMethod)#%d (2) {
&object(ReflectionMethod)#2 (2) {
["name"]=>
string(11) "__construct"
["class"]=>
string(8) "DateTime"
}
[1]=>
&object(ReflectionMethod)#%d (2) {
&object(ReflectionMethod)#3 (2) {
["name"]=>
string(8) "__wakeup"
["class"]=>
string(8) "DateTime"
}
[2]=>
&object(ReflectionMethod)#%d (2) {
&object(ReflectionMethod)#4 (2) {
["name"]=>
string(11) "__set_state"
["class"]=>
string(8) "DateTime"
}
[3]=>
&object(ReflectionMethod)#%d (2) {
&object(ReflectionMethod)#5 (2) {
["name"]=>
string(16) "createFromFormat"
string(10) "__toString"
["class"]=>
string(8) "DateTime"
}
[4]=>
&object(ReflectionMethod)#%d (2) {
&object(ReflectionMethod)#6 (2) {
["name"]=>
string(13) "getLastErrors"
string(16) "setDefaultFormat"
["class"]=>
string(8) "DateTime"
}
[5]=>
&object(ReflectionMethod)#%d (2) {
&object(ReflectionMethod)#7 (2) {
["name"]=>
string(6) "format"
string(16) "getDefaultFormat"
["class"]=>
string(8) "DateTime"
}
[6]=>
&object(ReflectionMethod)#%d (2) {
&object(ReflectionMethod)#8 (2) {
["name"]=>
string(6) "modify"
string(16) "createFromFormat"
["class"]=>
string(8) "DateTime"
}
[7]=>
&object(ReflectionMethod)#%d (2) {
&object(ReflectionMethod)#9 (2) {
["name"]=>
string(3) "add"
string(13) "getLastErrors"
["class"]=>
string(8) "DateTime"
}
[8]=>
&object(ReflectionMethod)#%d (2) {
&object(ReflectionMethod)#10 (2) {
["name"]=>
string(3) "sub"
string(6) "format"
["class"]=>
string(8) "DateTime"
}
[9]=>
&object(ReflectionMethod)#%d (2) {
&object(ReflectionMethod)#11 (2) {
["name"]=>
string(11) "getTimezone"
string(6) "modify"
["class"]=>
string(8) "DateTime"
}
[10]=>
&object(ReflectionMethod)#%d (2) {
&object(ReflectionMethod)#12 (2) {
["name"]=>
string(11) "setTimezone"
string(3) "add"
["class"]=>
string(8) "DateTime"
}
[11]=>
&object(ReflectionMethod)#%d (2) {
&object(ReflectionMethod)#13 (2) {
["name"]=>
string(9) "getOffset"
string(3) "sub"
["class"]=>
string(8) "DateTime"
}
[12]=>
&object(ReflectionMethod)#%d (2) {
&object(ReflectionMethod)#14 (2) {
["name"]=>
string(7) "setTime"
string(11) "getTimezone"
["class"]=>
string(8) "DateTime"
}
[13]=>
&object(ReflectionMethod)#%d (2) {
&object(ReflectionMethod)#15 (2) {
["name"]=>
string(7) "setDate"
string(11) "setTimezone"
["class"]=>
string(8) "DateTime"
}
[14]=>
&object(ReflectionMethod)#%d (2) {
&object(ReflectionMethod)#16 (2) {
["name"]=>
string(10) "setISODate"
string(9) "getOffset"
["class"]=>
string(8) "DateTime"
}
[15]=>
&object(ReflectionMethod)#%d (2) {
&object(ReflectionMethod)#17 (2) {
["name"]=>
string(12) "setTimestamp"
string(7) "setTime"
["class"]=>
string(8) "DateTime"
}
[16]=>
&object(ReflectionMethod)#%d (2) {
&object(ReflectionMethod)#18 (2) {
["name"]=>
string(12) "getTimestamp"
string(7) "setDate"
["class"]=>
string(8) "DateTime"
}
[17]=>
&object(ReflectionMethod)#%d (2) {
&object(ReflectionMethod)#19 (2) {
["name"]=>
string(10) "setISODate"
["class"]=>
string(8) "DateTime"
}
[18]=>
&object(ReflectionMethod)#20 (2) {
["name"]=>
string(12) "setTimestamp"
["class"]=>
string(8) "DateTime"
}
[19]=>
&object(ReflectionMethod)#21 (2) {
["name"]=>
string(12) "getTimestamp"
["class"]=>
string(8) "DateTime"
}
[20]=>
&object(ReflectionMethod)#22 (2) {
["name"]=>
string(4) "diff"
["class"]=>
Expand Down