Skip to content

Commit bfb9922

Browse files
committed
Merged pull request #12413
2 parents b67c232 + 8577d88 commit bfb9922

File tree

6 files changed

+415
-3
lines changed

6 files changed

+415
-3
lines changed

NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ PHP NEWS
55
Core:
66
. Added zend_call_stack_get implementation for NetBSD. (David Carlier)
77

8+
Date:
9+
. Added DateTime[Immutable]::createFromTimestamp. (Marc Bennewitz)
10+
811
DOM:
912
. Added DOMNode::compareDocumentPosition(). (nielsdos)
1013
. Implement #53655 (Improve speed of DOMNode::C14N() on large XML documents).

ext/date/php_date.c

Lines changed: 110 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2500,6 +2500,49 @@ PHPAPI bool php_date_initialize(php_date_obj *dateobj, const char *time_str, siz
25002500
return 1;
25012501
} /* }}} */
25022502

2503+
PHPAPI void php_date_initialize_from_ts_long(php_date_obj *dateobj, zend_long sec, int usec) /* {{{ */
2504+
{
2505+
dateobj->time = timelib_time_ctor();
2506+
dateobj->time->zone_type = TIMELIB_ZONETYPE_OFFSET;
2507+
2508+
timelib_unixtime2gmt(dateobj->time, (timelib_sll)sec);
2509+
timelib_update_ts(dateobj->time, NULL);
2510+
php_date_set_time_fraction(dateobj->time, usec);
2511+
} /* }}} */
2512+
2513+
PHPAPI bool php_date_initialize_from_ts_double(php_date_obj *dateobj, double ts) /* {{{ */
2514+
{
2515+
double sec_dval = trunc(ts);
2516+
zend_long sec;
2517+
int usec;
2518+
2519+
if (UNEXPECTED(isnan(sec_dval)
2520+
|| sec_dval >= (double)TIMELIB_LONG_MAX
2521+
|| sec_dval < (double)TIMELIB_LONG_MIN
2522+
)) {
2523+
zend_throw_error(
2524+
date_ce_date_range_error,
2525+
"Seconds must be a finite number between " TIMELIB_LONG_FMT " and " TIMELIB_LONG_FMT ", %g given",
2526+
TIMELIB_LONG_MIN,
2527+
TIMELIB_LONG_MAX,
2528+
sec_dval
2529+
);
2530+
return false;
2531+
}
2532+
2533+
sec = (zend_long)sec_dval;
2534+
usec = (int)(fmod(ts, 1) * 1000000);
2535+
2536+
if (UNEXPECTED(usec < 0)) {
2537+
sec = sec - 1;
2538+
usec = 1000000 + usec;
2539+
}
2540+
2541+
php_date_initialize_from_ts_long(dateobj, sec, usec);
2542+
2543+
return true;
2544+
} /* }}} */
2545+
25032546
/* {{{ Returns new DateTime object */
25042547
PHP_FUNCTION(date_create)
25052548
{
@@ -2564,7 +2607,7 @@ PHP_FUNCTION(date_create_from_format)
25642607
}
25652608
/* }}} */
25662609

2567-
/* {{{ Returns new DateTime object formatted according to the specified format */
2610+
/* {{{ Returns new DateTimeImmutable object formatted according to the specified format */
25682611
PHP_FUNCTION(date_create_immutable_from_format)
25692612
{
25702613
zval *timezone_object = NULL;
@@ -2662,6 +2705,39 @@ PHP_METHOD(DateTime, createFromInterface)
26622705
}
26632706
/* }}} */
26642707

2708+
/* {{{ Creates new DateTime object from given unix timetamp */
2709+
PHP_METHOD(DateTime, createFromTimestamp)
2710+
{
2711+
zval *value;
2712+
zval new_object;
2713+
php_date_obj *new_dateobj;
2714+
2715+
ZEND_PARSE_PARAMETERS_START(1, 1)
2716+
Z_PARAM_NUMBER(value)
2717+
ZEND_PARSE_PARAMETERS_END();
2718+
2719+
php_date_instantiate(execute_data->This.value.ce ? execute_data->This.value.ce : date_ce_date, &new_object);
2720+
new_dateobj = Z_PHPDATE_P(&new_object);
2721+
2722+
switch (Z_TYPE_P(value)) {
2723+
case IS_LONG:
2724+
php_date_initialize_from_ts_long(new_dateobj, Z_LVAL_P(value), 0);
2725+
break;
2726+
2727+
case IS_DOUBLE:
2728+
if (!php_date_initialize_from_ts_double(new_dateobj, Z_DVAL_P(value))) {
2729+
zval_ptr_dtor(&new_object);
2730+
RETURN_THROWS();
2731+
}
2732+
break;
2733+
2734+
EMPTY_SWITCH_DEFAULT_CASE();
2735+
}
2736+
2737+
RETURN_OBJ(Z_OBJ(new_object));
2738+
}
2739+
/* }}} */
2740+
26652741
/* {{{ Creates new DateTimeImmutable object from an existing mutable DateTime object. */
26662742
PHP_METHOD(DateTimeImmutable, createFromMutable)
26672743
{
@@ -2704,6 +2780,39 @@ PHP_METHOD(DateTimeImmutable, createFromInterface)
27042780
}
27052781
/* }}} */
27062782

2783+
/* {{{ Creates new DateTimeImmutable object from given unix timestamp */
2784+
PHP_METHOD(DateTimeImmutable, createFromTimestamp)
2785+
{
2786+
zval *value;
2787+
zval new_object;
2788+
php_date_obj *new_dateobj;
2789+
2790+
ZEND_PARSE_PARAMETERS_START(1, 1)
2791+
Z_PARAM_NUMBER(value)
2792+
ZEND_PARSE_PARAMETERS_END();
2793+
2794+
php_date_instantiate(execute_data->This.value.ce ? execute_data->This.value.ce : date_ce_immutable, &new_object);
2795+
new_dateobj = Z_PHPDATE_P(&new_object);
2796+
2797+
switch (Z_TYPE_P(value)) {
2798+
case IS_LONG:
2799+
php_date_initialize_from_ts_long(new_dateobj, Z_LVAL_P(value), 0);
2800+
break;
2801+
2802+
case IS_DOUBLE:
2803+
if (!php_date_initialize_from_ts_double(new_dateobj, Z_DVAL_P(value))) {
2804+
zval_ptr_dtor(&new_object);
2805+
RETURN_THROWS();
2806+
}
2807+
break;
2808+
2809+
EMPTY_SWITCH_DEFAULT_CASE();
2810+
}
2811+
2812+
RETURN_OBJ(Z_OBJ(new_object));
2813+
}
2814+
/* }}} */
2815+
27072816
static bool php_date_initialize_from_hash(php_date_obj **dateobj, HashTable *myht)
27082817
{
27092818
zval *z_date;

ext/date/php_date.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ PHPAPI zend_class_entry *php_date_get_period_ce(void);
142142

143143
PHPAPI zval *php_date_instantiate(zend_class_entry *pce, zval *object);
144144
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);
145-
145+
PHPAPI void php_date_initialize_from_ts_long(php_date_obj *dateobj, zend_long sec, int usec);
146+
PHPAPI bool php_date_initialize_from_ts_double(php_date_obj *dateobj, double ts);
146147

147148
#endif /* PHP_DATE_H */

ext/date/php_date.stub.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,9 @@ public static function createFromInterface(DateTimeInterface $object): DateTime
362362
*/
363363
public static function createFromFormat(string $format, string $datetime, ?DateTimeZone $timezone = null): DateTime|false {}
364364

365+
/** @tentative-return-type */
366+
public static function createFromTimestamp(int|float $timestamp): static {}
367+
365368
/**
366369
* @return array<string, int|array>|false
367370
* @tentative-return-type
@@ -466,6 +469,9 @@ public static function __set_state(array $array): DateTimeImmutable {}
466469
*/
467470
public static function createFromFormat(string $format, string $datetime, ?DateTimeZone $timezone = null): DateTimeImmutable|false {}
468471

472+
/** @tentative-return-type */
473+
public static function createFromTimestamp(int|float $timestamp): static {}
474+
469475
/**
470476
* @return array<string, int|array>|false
471477
* @tentative-return-type

ext/date/php_date_arginfo.h

Lines changed: 11 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)