Skip to content

Commit 2ee2335

Browse files
committed
Fixed bug #80057 (DateTimeImmutable::createFromFormat() does not populate time)
1 parent 36cdbd0 commit 2ee2335

File tree

4 files changed

+36
-9
lines changed

4 files changed

+36
-9
lines changed

NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ PHP NEWS
88
. Fixed bug #80045 (memleak after two set_exception_handler calls with
99
__call). (Nikita)
1010

11+
- Date:
12+
. Fixed bug #80057 (DateTimeImmutable::createFromFormat() does not populate
13+
time). (Derick)
14+
1115
03 Sep 2020, PHP 8.0.0beta3
1216

1317
- Calendar:

ext/date/php_date.c

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -707,7 +707,7 @@ static zend_string *date_format(const char *format, size_t format_len, timelib_t
707707

708708
/* timezone */
709709
case 'I': length = slprintf(buffer, sizeof(buffer), "%d", localtime ? offset->is_dst : 0); break;
710-
case 'p':
710+
case 'p':
711711
if (!localtime || strcmp(offset->abbr, "UTC") == 0 || strcmp(offset->abbr, "Z") == 0) {
712712
length = slprintf(buffer, sizeof(buffer), "%s", "Z");
713713
break;
@@ -2179,7 +2179,7 @@ static void php_date_get_current_time_with_fraction(time_t *sec, suseconds_t *us
21792179
#endif
21802180
}
21812181

2182-
PHPAPI int php_date_initialize(php_date_obj *dateobj, const char *time_str, size_t time_str_len, const char *format, zval *timezone_object, int ctor) /* {{{ */
2182+
PHPAPI int php_date_initialize(php_date_obj *dateobj, const char *time_str, size_t time_str_len, const char *format, zval *timezone_object, int flags) /* {{{ */
21832183
{
21842184
timelib_time *now;
21852185
timelib_tzinfo *tzi = NULL;
@@ -2189,6 +2189,7 @@ PHPAPI int php_date_initialize(php_date_obj *dateobj, const char *time_str, size
21892189
timelib_sll new_offset = 0;
21902190
time_t sec;
21912191
suseconds_t usec;
2192+
int options = 0;
21922193

21932194
if (dateobj->time) {
21942195
timelib_time_dtor(dateobj->time);
@@ -2210,7 +2211,7 @@ PHPAPI int php_date_initialize(php_date_obj *dateobj, const char *time_str, size
22102211
update_errors_warnings(err);
22112212

22122213

2213-
if (ctor && err && err->error_count) {
2214+
if ((flags & PHP_DATE_INIT_CTOR) && err && err->error_count) {
22142215
/* spit out the first library error message, at least */
22152216
php_error_docref(NULL, E_WARNING, "Failed to parse time string (%s) at position %d (%c): %s", time_str,
22162217
err->error_messages[0].position, err->error_messages[0].character, err->error_messages[0].message);
@@ -2263,7 +2264,13 @@ PHPAPI int php_date_initialize(php_date_obj *dateobj, const char *time_str, size
22632264
php_date_get_current_time_with_fraction(&sec, &usec);
22642265
timelib_unixtime2local(now, (timelib_sll) sec);
22652266
php_date_set_time_fraction(now, usec);
2266-
timelib_fill_holes(dateobj->time, now, TIMELIB_NO_CLONE);
2267+
2268+
options = TIMELIB_NO_CLONE;
2269+
if (flags & PHP_DATE_INIT_FORMAT) {
2270+
options |= TIMELIB_OVERRIDE_TIME;
2271+
}
2272+
timelib_fill_holes(dateobj->time, now, options);
2273+
22672274
timelib_update_ts(dateobj->time, tzi);
22682275
timelib_update_from_sse(dateobj->time);
22692276

@@ -2331,7 +2338,7 @@ PHP_FUNCTION(date_create_from_format)
23312338
ZEND_PARSE_PARAMETERS_END();
23322339

23332340
php_date_instantiate(execute_data->This.value.ce ? execute_data->This.value.ce : date_ce_date, return_value);
2334-
if (!php_date_initialize(Z_PHPDATE_P(return_value), time_str, time_str_len, format_str, timezone_object, 0)) {
2341+
if (!php_date_initialize(Z_PHPDATE_P(return_value), time_str, time_str_len, format_str, timezone_object, PHP_DATE_INIT_FORMAT)) {
23352342
zval_ptr_dtor(return_value);
23362343
RETURN_FALSE;
23372344
}
@@ -2353,7 +2360,7 @@ PHP_FUNCTION(date_create_immutable_from_format)
23532360
ZEND_PARSE_PARAMETERS_END();
23542361

23552362
php_date_instantiate(execute_data->This.value.ce ? execute_data->This.value.ce : date_ce_immutable, return_value);
2356-
if (!php_date_initialize(Z_PHPDATE_P(return_value), time_str, time_str_len, format_str, timezone_object, 0)) {
2363+
if (!php_date_initialize(Z_PHPDATE_P(return_value), time_str, time_str_len, format_str, timezone_object, PHP_DATE_INIT_FORMAT)) {
23572364
zval_ptr_dtor(return_value);
23582365
RETURN_FALSE;
23592366
}
@@ -2375,7 +2382,7 @@ PHP_METHOD(DateTime, __construct)
23752382
ZEND_PARSE_PARAMETERS_END();
23762383

23772384
zend_replace_error_handling(EH_THROW, NULL, &error_handling);
2378-
php_date_initialize(Z_PHPDATE_P(ZEND_THIS), time_str, time_str_len, NULL, timezone_object, 1);
2385+
php_date_initialize(Z_PHPDATE_P(ZEND_THIS), time_str, time_str_len, NULL, timezone_object, PHP_DATE_INIT_CTOR);
23792386
zend_restore_error_handling(&error_handling);
23802387
}
23812388
/* }}} */
@@ -2395,7 +2402,7 @@ PHP_METHOD(DateTimeImmutable, __construct)
23952402
ZEND_PARSE_PARAMETERS_END();
23962403

23972404
zend_replace_error_handling(EH_THROW, NULL, &error_handling);
2398-
php_date_initialize(Z_PHPDATE_P(ZEND_THIS), time_str, time_str_len, NULL, timezone_object, 1);
2405+
php_date_initialize(Z_PHPDATE_P(ZEND_THIS), time_str, time_str_len, NULL, timezone_object, PHP_DATE_INIT_CTOR);
23992406
zend_restore_error_handling(&error_handling);
24002407
}
24012408
/* }}} */

ext/date/php_date.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,11 @@ PHPAPI zend_class_entry *php_date_get_interval_ce(void);
130130
PHPAPI zend_class_entry *php_date_get_period_ce(void);
131131

132132
/* Functions for creating DateTime objects, and initializing them from a string */
133+
#define PHP_DATE_INIT_CTOR 0x01
134+
#define PHP_DATE_INIT_FORMAT 0x02
135+
133136
PHPAPI zval *php_date_instantiate(zend_class_entry *pce, zval *object);
134-
PHPAPI int php_date_initialize(php_date_obj *dateobj, const char *time_str, size_t time_str_len, const char *format, zval *timezone_object, int ctor);
137+
PHPAPI int php_date_initialize(php_date_obj *dateobj, const char *time_str, size_t time_str_len, const char *format, zval *timezone_object, int flags);
135138

136139

137140
#endif /* PHP_DATE_H */

ext/date/tests/bug80057.phpt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
--TEST--
2+
Bug #80057 (DateTimeImmutable::createFromFormat() does not populate time)
3+
--FILE--
4+
<?php
5+
$now = new DateTimeImmutable;
6+
$parsed = DateTimeImmutable::createFromFormat('Y-m-d', '2020-09-04');
7+
$nowStr = $now->format("H:i");
8+
$parsedStr = $parsed->format("H:i");
9+
10+
var_dump($nowStr == $parsedStr);
11+
?>
12+
--EXPECT--
13+
bool(true)

0 commit comments

Comments
 (0)