diff --git a/ext/date/php_date.c b/ext/date/php_date.c index ae7f62fb8f734..495a226543c0e 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -2481,35 +2481,40 @@ PHPAPI bool php_date_initialize(php_date_obj *dateobj, const char *time_str, siz return 1; } /* }}} */ -PHPAPI void php_date_initialize_from_ts_long(php_date_obj *dateobj, zend_long sec, int usec) /* {{{ */ +PHPAPI void php_date_initialize_from_ts_sll(php_date_obj *dateobj, timelib_sll sec, int usec) /* {{{ */ { dateobj->time = timelib_time_ctor(); dateobj->time->zone_type = TIMELIB_ZONETYPE_OFFSET; - timelib_unixtime2gmt(dateobj->time, (timelib_sll)sec); + timelib_unixtime2gmt(dateobj->time, sec); timelib_update_ts(dateobj->time, NULL); php_date_set_time_fraction(dateobj->time, usec); } /* }}} */ +PHPAPI void php_date_initialize_from_ts_long(php_date_obj *dateobj, zend_long sec, int usec) /* {{{ */ +{ + php_date_initialize_from_ts_sll(dateobj, (timelib_sll)sec, usec); +} /* }}} */ + PHPAPI bool php_date_initialize_from_ts_double(php_date_obj *dateobj, double ts) /* {{{ */ { double sec_dval = trunc(ts); - zend_long sec; + timelib_sll sec; int usec; - if (UNEXPECTED(isnan(sec_dval) || !PHP_DATE_DOUBLE_FITS_LONG(sec_dval))) { + if (UNEXPECTED(isnan(sec_dval) || !PHP_DATE_DOUBLE_FITS_SLL(sec_dval))) { zend_argument_error( date_ce_date_range_error, 1, - "must be a finite number between " TIMELIB_LONG_FMT " and " TIMELIB_LONG_FMT ".999999, %g given", - TIMELIB_LONG_MIN, - TIMELIB_LONG_MAX, + "must be a finite number between " PHP_DATE_SLL_FMT " and " PHP_DATE_SLL_FMT ".999999, %g given", + INT64_MIN, + INT64_MAX, ts ); return false; } - sec = (zend_long)sec_dval; + sec = (timelib_sll)sec_dval; usec = (int) round(fmod(ts, 1) * 1000000); if (UNEXPECTED(abs(usec) == 1000000)) { @@ -2518,13 +2523,13 @@ PHPAPI bool php_date_initialize_from_ts_double(php_date_obj *dateobj, double ts) } if (UNEXPECTED(usec < 0)) { - if (UNEXPECTED(sec == TIMELIB_LONG_MIN)) { + if (UNEXPECTED(sec == INT64_MAX)) { zend_argument_error( date_ce_date_range_error, 1, - "must be a finite number between " TIMELIB_LONG_FMT " and " TIMELIB_LONG_FMT ".999999, %g given", - TIMELIB_LONG_MIN, - TIMELIB_LONG_MAX, + "must be a finite number between " PHP_DATE_SLL_FMT " and " PHP_DATE_SLL_FMT ".999999, %g given", + INT64_MIN, + INT64_MAX, ts ); return false; @@ -2534,7 +2539,7 @@ PHPAPI bool php_date_initialize_from_ts_double(php_date_obj *dateobj, double ts) usec = 1000000 + usec; } - php_date_initialize_from_ts_long(dateobj, sec, usec); + php_date_initialize_from_ts_sll(dateobj, sec, usec); return true; } /* }}} */ diff --git a/ext/date/php_date.h b/ext/date/php_date.h index f5f43bc7dfb0f..26960a04d125e 100644 --- a/ext/date/php_date.h +++ b/ext/date/php_date.h @@ -37,6 +37,12 @@ # define PHP_DATE_DOUBLE_FITS_LONG(d) (!((d) >= (double)TIMELIB_LONG_MAX || (d) < (double)TIMELIB_LONG_MIN)) #endif +/* Same as PHP_DATE_SIZEOF_LONG but for timelib_sll (int64_t) */ +#define PHP_DATE_DOUBLE_FITS_SLL(d) (!((d) >= (double)INT64_MAX || (d) < (double)INT64_MIN)) + +/* Same as TIMELIB_LONG_FMT but for timelib_sll (int64_t) */ +#define PHP_DATE_SLL_FMT "%" PRId64 + #include "php_version.h" #define PHP_DATE_VERSION PHP_VERSION @@ -160,6 +166,7 @@ PHPAPI zend_class_entry *php_date_get_period_ce(void); PHPAPI zval *php_date_instantiate(zend_class_entry *pce, zval *object); PHPAPI bool php_date_initialize(php_date_obj *dateobj, const char *time_str, size_t time_str_len, const char *format, zval *timezone_object, int flags); +PHPAPI void php_date_initialize_from_ts_sll(php_date_obj *dateobj, timelib_sll sec, int usec); PHPAPI void php_date_initialize_from_ts_long(php_date_obj *dateobj, zend_long sec, int usec); PHPAPI bool php_date_initialize_from_ts_double(php_date_obj *dateobj, double ts); diff --git a/ext/date/tests/createFromTimestamp.phpt b/ext/date/tests/createFromTimestamp.phpt index f31aeae118547..c792de741a35e 100644 --- a/ext/date/tests/createFromTimestamp.phpt +++ b/ext/date/tests/createFromTimestamp.phpt @@ -18,13 +18,15 @@ $timestamps = array( 0, 0.0, -0.0, - PHP_INT_MAX + 1024.0, - PHP_INT_MIN - 1025.0, + 9223372036854775808.0, // INT64_MAX + 1 + -9223372036854777856.0, // INT64_MIN - 2048 NAN, +INF, -INF, 1599828571.235628, -1599828571.235628, + 2147483648.0, // INT32_MAX + 1 + -2147483649.0, // INT32_MIN - 1 ); foreach ($timestamps as $ts) { @@ -245,6 +247,38 @@ DateTimeImmutable::createFromTimestamp(-1599828571.235628): object(DateTimeImmut ["timezone"]=> string(6) "+00:00" } +DateTime::createFromTimestamp(2147483648.0): object(DateTime)#%d (3) { + ["date"]=> + string(26) "2038-01-19 03:14:08.000000" + ["timezone_type"]=> + int(1) + ["timezone"]=> + string(6) "+00:00" +} +DateTimeImmutable::createFromTimestamp(2147483648.0): object(DateTimeImmutable)#%d (3) { + ["date"]=> + string(26) "2038-01-19 03:14:08.000000" + ["timezone_type"]=> + int(1) + ["timezone"]=> + string(6) "+00:00" +} +DateTime::createFromTimestamp(-2147483649.0): object(DateTime)#%d (3) { + ["date"]=> + string(26) "1901-12-13 20:45:51.000000" + ["timezone_type"]=> + int(1) + ["timezone"]=> + string(6) "+00:00" +} +DateTimeImmutable::createFromTimestamp(-2147483649.0): object(DateTimeImmutable)#%d (3) { + ["date"]=> + string(26) "1901-12-13 20:45:51.000000" + ["timezone_type"]=> + int(1) + ["timezone"]=> + string(6) "+00:00" +} MyDateTime::createFromTimestamp(0): object(MyDateTime)#%d (3) { ["date"]=> string(26) "1970-01-01 00:00:00.000000" diff --git a/ext/date/tests/createFromTimestamp_32bit.phpt b/ext/date/tests/createFromTimestamp_32bit.phpt deleted file mode 100644 index 8052acfca135a..0000000000000 --- a/ext/date/tests/createFromTimestamp_32bit.phpt +++ /dev/null @@ -1,126 +0,0 @@ ---TEST-- -Tests for DateTime[Immutable]::createFromTimestamp 32bit variant ---SKIPIF-- - ---INI-- -date.timezone=Europe/London ---FILE-- -getMessage() . "\n"; - } - - echo 'DateTimeImmutable::createFromTimestamp(' . var_export($ts, true) . '): '; - try { - var_dump(DateTimeImmutable::createFromTimestamp($ts)); - } catch (Throwable $e) { - echo get_class($e) . ': ' . $e->getMessage() . "\n"; - } -} - -?> ---EXPECTF-- -DateTime::createFromTimestamp(2147483647): object(DateTime)#%d (3) { - ["date"]=> - string(26) "2038-01-19 03:14:07.000000" - ["timezone_type"]=> - int(1) - ["timezone"]=> - string(6) "+00:00" -} -DateTimeImmutable::createFromTimestamp(2147483647): object(DateTimeImmutable)#%d (3) { - ["date"]=> - string(26) "2038-01-19 03:14:07.000000" - ["timezone_type"]=> - int(1) - ["timezone"]=> - string(6) "+00:00" -} -DateTime::createFromTimestamp(-2147483647-1): object(DateTime)#%d (3) { - ["date"]=> - string(26) "1901-12-13 20:45:52.000000" - ["timezone_type"]=> - int(1) - ["timezone"]=> - string(6) "+00:00" -} -DateTimeImmutable::createFromTimestamp(-2147483647-1): object(DateTimeImmutable)#%d (3) { - ["date"]=> - string(26) "1901-12-13 20:45:52.000000" - ["timezone_type"]=> - int(1) - ["timezone"]=> - string(6) "+00:00" -} -DateTime::createFromTimestamp(2147483647.5): object(DateTime)#%d (3) { - ["date"]=> - string(26) "2038-01-19 03:14:07.500000" - ["timezone_type"]=> - int(1) - ["timezone"]=> - string(6) "+00:00" -} -DateTimeImmutable::createFromTimestamp(2147483647.5): object(DateTimeImmutable)#%d (3) { - ["date"]=> - string(26) "2038-01-19 03:14:07.500000" - ["timezone_type"]=> - int(1) - ["timezone"]=> - string(6) "+00:00" -} -DateTime::createFromTimestamp(-2147483647.5): object(DateTime)#%d (3) { - ["date"]=> - string(26) "1901-12-13 20:45:52.500000" - ["timezone_type"]=> - int(1) - ["timezone"]=> - string(6) "+00:00" -} -DateTimeImmutable::createFromTimestamp(-2147483647.5): object(DateTimeImmutable)#%d (3) { - ["date"]=> - string(26) "1901-12-13 20:45:52.500000" - ["timezone_type"]=> - int(1) - ["timezone"]=> - string(6) "+00:00" -} -DateTime::createFromTimestamp(2147483646.5): object(DateTime)#%d (3) { - ["date"]=> - string(26) "2038-01-19 03:14:06.500000" - ["timezone_type"]=> - int(1) - ["timezone"]=> - string(6) "+00:00" -} -DateTimeImmutable::createFromTimestamp(2147483646.5): object(DateTimeImmutable)#%d (3) { - ["date"]=> - string(26) "2038-01-19 03:14:06.500000" - ["timezone_type"]=> - int(1) - ["timezone"]=> - string(6) "+00:00" -} -DateTime::createFromTimestamp(-2147483648.5): DateRangeError: DateTime::createFromTimestamp(): Argument #1 ($timestamp) must be a finite number between -2147483648 and 2147483647.999999, -2.14748e+9 given -DateTimeImmutable::createFromTimestamp(-2147483648.5): DateRangeError: DateTimeImmutable::createFromTimestamp(): Argument #1 ($timestamp) must be a finite number between -2147483648 and 2147483647.999999, -2.14748e+9 given -DateTime::createFromTimestamp(2147484671.0): DateRangeError: DateTime::createFromTimestamp(): Argument #1 ($timestamp) must be a finite number between -2147483648 and 2147483647.999999, 2.14748e+9 given -DateTimeImmutable::createFromTimestamp(2147484671.0): DateRangeError: DateTimeImmutable::createFromTimestamp(): Argument #1 ($timestamp) must be a finite number between -2147483648 and 2147483647.999999, 2.14748e+9 given -DateTime::createFromTimestamp(-2147484673.0): DateRangeError: DateTime::createFromTimestamp(): Argument #1 ($timestamp) must be a finite number between -2147483648 and 2147483647.999999, -2.14748e+9 given -DateTimeImmutable::createFromTimestamp(-2147484673.0): DateRangeError: DateTimeImmutable::createFromTimestamp(): Argument #1 ($timestamp) must be a finite number between -2147483648 and 2147483647.999999, -2.14748e+9 given