Added DateTime[Immutable]::[get|set]Microseconds (#12557)

* Added DateTime[Immutable]::[get|set]Microseconds
This commit is contained in:
Marc Bennewitz 2024-02-05 13:14:18 +01:00 committed by GitHub
parent f91833d297
commit 0016b3085c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 314 additions and 2 deletions

1
NEWS
View File

@ -19,6 +19,7 @@ PHP NEWS
- Date:
. Added DateTime[Immutable]::createFromTimestamp. (Marc Bennewitz)
. Added DateTime[Immutable]::[get|set]Microseconds. (Marc Bennewitz)
- DOM:
. Added DOMNode::compareDocumentPosition(). (nielsdos)

View File

@ -146,6 +146,9 @@ PHP 8.4 UPGRADE NOTES
- Date:
. Added static methods
DateTime[Immutable]::createFromTimestamp(int|float $timestamp): static.
. Added method DateTime[Immutable]::getMicroseconds(): int.
. Added method
DateTime[Immutable]::setMicroseconds(int $microseconds): static.
- DOM:
. Added constant DOMNode::DOCUMENT_POSITION_DISCONNECTED.

View File

@ -3844,12 +3844,76 @@ PHP_METHOD(DateTimeImmutable, setTimestamp)
}
/* }}} */
/* {{{ */
PHP_METHOD(DateTimeImmutable, setMicroseconds)
{
zval *object, new_object;
php_date_obj *dateobj, *new_dateobj;
zend_long us;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &us) == FAILURE) {
RETURN_THROWS();
}
if (UNEXPECTED(us < 0 || us > 999999)) {
zend_argument_error(
date_ce_date_range_error,
1,
"must be between 0 and 999999, " ZEND_LONG_FMT " given",
us
);
RETURN_THROWS();
}
object = ZEND_THIS;
dateobj = Z_PHPDATE_P(object);
DATE_CHECK_INITIALIZED(dateobj->time, Z_OBJCE_P(object));
date_clone_immutable(object, &new_object);
new_dateobj = Z_PHPDATE_P(&new_object);
php_date_set_time_fraction(new_dateobj->time, (int)us);
RETURN_OBJ(Z_OBJ(new_object));
}
/* }}} */
/* {{{ */
PHP_METHOD(DateTime, setMicroseconds)
{
zval *object;
php_date_obj *dateobj;
zend_long us;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &us) == FAILURE) {
RETURN_THROWS();
}
if (UNEXPECTED(us < 0 || us > 999999)) {
zend_argument_error(
date_ce_date_range_error,
1,
"must be between 0 and 999999, " ZEND_LONG_FMT " given",
us
);
RETURN_THROWS();
}
object = ZEND_THIS;
dateobj = Z_PHPDATE_P(object);
DATE_CHECK_INITIALIZED(dateobj->time, Z_OBJCE_P(object));
php_date_set_time_fraction(dateobj->time, (int)us);
RETURN_OBJ_COPY(Z_OBJ_P(object));
}
/* }}} */
/* {{{ Gets the Unix timestamp. */
PHP_FUNCTION(date_timestamp_get)
{
zval *object;
php_date_obj *dateobj;
zend_long timestamp;
zend_long timestamp;
int epoch_does_not_fit_in_zend_long;
if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &object, date_ce_interface) == FAILURE) {
@ -3873,6 +3937,21 @@ PHP_FUNCTION(date_timestamp_get)
}
/* }}} */
PHP_METHOD(DateTime, getMicroseconds) /* {{{ */
{
zval *object;
php_date_obj *dateobj;
ZEND_PARSE_PARAMETERS_NONE();
object = ZEND_THIS;
dateobj = Z_PHPDATE_P(object);
DATE_CHECK_INITIALIZED(dateobj->time, Z_OBJCE_P(object));
RETURN_LONG((zend_long)dateobj->time->us);
}
/* }}} */
/* {{{ Returns the difference between two DateTime objects. */
PHP_FUNCTION(date_diff)
{

View File

@ -412,6 +412,9 @@ class DateTime implements DateTimeInterface
*/
public function getOffset(): int {}
/** @tentative-return-type */
public function getMicroseconds(): int {}
/**
* @tentative-return-type
* @alias date_time_set
@ -436,6 +439,9 @@ class DateTime implements DateTimeInterface
*/
public function setTimestamp(int $timestamp): DateTime {}
/** @tentative-return-type */
public function setMicroseconds(int $microseconds): static {}
/**
* @tentative-return-type
* @alias date_timestamp_get
@ -503,6 +509,12 @@ class DateTimeImmutable implements DateTimeInterface
*/
public function getTimestamp(): int {}
/**
* @alias DateTime::getMicroseconds
* @tentative-return-type
*/
public function getMicroseconds(): int {}
/**
* @tentative-return-type
* @alias date_diff
@ -533,6 +545,9 @@ class DateTimeImmutable implements DateTimeInterface
/** @tentative-return-type */
public function setTimestamp(int $timestamp): DateTimeImmutable {}
/** @tentative-return-type */
public function setMicroseconds(int $microseconds): static {}
/** @tentative-return-type */
public static function createFromMutable(DateTime $object): static {}

View File

@ -1,5 +1,5 @@
/* This is a generated file, edit the .stub.php file instead.
* Stub hash: 1445f6053da5ca9dc7bb618f2eadc4a8ea56a15f */
* Stub hash: 6fb121a5992ae96d12dea6055d1b0f0d6534cf21 */
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_strtotime, 0, 1, MAY_BE_LONG|MAY_BE_FALSE)
ZEND_ARG_TYPE_INFO(0, datetime, IS_STRING, 0)
@ -307,6 +307,8 @@ ZEND_END_ARG_INFO()
#define arginfo_class_DateTime_getOffset arginfo_class_DateTimeInterface_getOffset
#define arginfo_class_DateTime_getMicroseconds arginfo_class_DateTimeInterface_getOffset
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_INFO_EX(arginfo_class_DateTime_setTime, 0, 2, DateTime, 0)
ZEND_ARG_TYPE_INFO(0, hour, IS_LONG, 0)
ZEND_ARG_TYPE_INFO(0, minute, IS_LONG, 0)
@ -330,6 +332,10 @@ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_INFO_EX(arginfo_class_DateTime_setTimes
ZEND_ARG_TYPE_INFO(0, timestamp, IS_LONG, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_DateTime_setMicroseconds, 0, 1, IS_STATIC, 0)
ZEND_ARG_TYPE_INFO(0, microseconds, IS_LONG, 0)
ZEND_END_ARG_INFO()
#define arginfo_class_DateTime_getTimestamp arginfo_class_DateTimeInterface_getOffset
#define arginfo_class_DateTime_diff arginfo_class_DateTimeInterface_diff
@ -364,6 +370,8 @@ ZEND_END_ARG_INFO()
#define arginfo_class_DateTimeImmutable_getTimestamp arginfo_class_DateTimeInterface_getOffset
#define arginfo_class_DateTimeImmutable_getMicroseconds arginfo_class_DateTimeInterface_getOffset
#define arginfo_class_DateTimeImmutable_diff arginfo_class_DateTimeInterface_diff
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_DateTimeImmutable_modify, 0, 1, DateTimeImmutable, MAY_BE_FALSE)
@ -403,6 +411,8 @@ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_INFO_EX(arginfo_class_DateTimeImmutable
ZEND_ARG_TYPE_INFO(0, timestamp, IS_LONG, 0)
ZEND_END_ARG_INFO()
#define arginfo_class_DateTimeImmutable_setMicroseconds arginfo_class_DateTime_setMicroseconds
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_DateTimeImmutable_createFromMutable, 0, 1, IS_STATIC, 0)
ZEND_ARG_OBJ_INFO(0, object, DateTime, 0)
ZEND_END_ARG_INFO()
@ -563,6 +573,8 @@ ZEND_METHOD(DateTime, createFromInterface);
ZEND_METHOD(DateTime, createFromTimestamp);
ZEND_METHOD(DateTime, modify);
ZEND_METHOD(DateTime, sub);
ZEND_METHOD(DateTime, getMicroseconds);
ZEND_METHOD(DateTime, setMicroseconds);
ZEND_METHOD(DateTimeImmutable, __construct);
ZEND_METHOD(DateTimeImmutable, __serialize);
ZEND_METHOD(DateTimeImmutable, __unserialize);
@ -577,6 +589,7 @@ ZEND_METHOD(DateTimeImmutable, setTime);
ZEND_METHOD(DateTimeImmutable, setDate);
ZEND_METHOD(DateTimeImmutable, setISODate);
ZEND_METHOD(DateTimeImmutable, setTimestamp);
ZEND_METHOD(DateTimeImmutable, setMicroseconds);
ZEND_METHOD(DateTimeImmutable, createFromMutable);
ZEND_METHOD(DateTimeImmutable, createFromInterface);
ZEND_METHOD(DateTimeZone, __construct);
@ -687,10 +700,12 @@ static const zend_function_entry class_DateTime_methods[] = {
ZEND_ME_MAPPING(getTimezone, date_timezone_get, arginfo_class_DateTime_getTimezone, ZEND_ACC_PUBLIC)
ZEND_ME_MAPPING(setTimezone, date_timezone_set, arginfo_class_DateTime_setTimezone, ZEND_ACC_PUBLIC)
ZEND_ME_MAPPING(getOffset, date_offset_get, arginfo_class_DateTime_getOffset, ZEND_ACC_PUBLIC)
ZEND_ME(DateTime, getMicroseconds, arginfo_class_DateTime_getMicroseconds, ZEND_ACC_PUBLIC)
ZEND_ME_MAPPING(setTime, date_time_set, arginfo_class_DateTime_setTime, ZEND_ACC_PUBLIC)
ZEND_ME_MAPPING(setDate, date_date_set, arginfo_class_DateTime_setDate, ZEND_ACC_PUBLIC)
ZEND_ME_MAPPING(setISODate, date_isodate_set, arginfo_class_DateTime_setISODate, ZEND_ACC_PUBLIC)
ZEND_ME_MAPPING(setTimestamp, date_timestamp_set, arginfo_class_DateTime_setTimestamp, ZEND_ACC_PUBLIC)
ZEND_ME(DateTime, setMicroseconds, arginfo_class_DateTime_setMicroseconds, ZEND_ACC_PUBLIC)
ZEND_ME_MAPPING(getTimestamp, date_timestamp_get, arginfo_class_DateTime_getTimestamp, ZEND_ACC_PUBLIC)
ZEND_ME_MAPPING(diff, date_diff, arginfo_class_DateTime_diff, ZEND_ACC_PUBLIC)
ZEND_FE_END
@ -710,6 +725,7 @@ static const zend_function_entry class_DateTimeImmutable_methods[] = {
ZEND_ME_MAPPING(getTimezone, date_timezone_get, arginfo_class_DateTimeImmutable_getTimezone, ZEND_ACC_PUBLIC)
ZEND_ME_MAPPING(getOffset, date_offset_get, arginfo_class_DateTimeImmutable_getOffset, ZEND_ACC_PUBLIC)
ZEND_ME_MAPPING(getTimestamp, date_timestamp_get, arginfo_class_DateTimeImmutable_getTimestamp, ZEND_ACC_PUBLIC)
ZEND_MALIAS(DateTime, getMicroseconds, getMicroseconds, arginfo_class_DateTimeImmutable_getMicroseconds, ZEND_ACC_PUBLIC)
ZEND_ME_MAPPING(diff, date_diff, arginfo_class_DateTimeImmutable_diff, ZEND_ACC_PUBLIC)
ZEND_ME(DateTimeImmutable, modify, arginfo_class_DateTimeImmutable_modify, ZEND_ACC_PUBLIC)
ZEND_ME(DateTimeImmutable, add, arginfo_class_DateTimeImmutable_add, ZEND_ACC_PUBLIC)
@ -719,6 +735,7 @@ static const zend_function_entry class_DateTimeImmutable_methods[] = {
ZEND_ME(DateTimeImmutable, setDate, arginfo_class_DateTimeImmutable_setDate, ZEND_ACC_PUBLIC)
ZEND_ME(DateTimeImmutable, setISODate, arginfo_class_DateTimeImmutable_setISODate, ZEND_ACC_PUBLIC)
ZEND_ME(DateTimeImmutable, setTimestamp, arginfo_class_DateTimeImmutable_setTimestamp, ZEND_ACC_PUBLIC)
ZEND_ME(DateTimeImmutable, setMicroseconds, arginfo_class_DateTimeImmutable_setMicroseconds, ZEND_ACC_PUBLIC)
ZEND_ME(DateTimeImmutable, createFromMutable, arginfo_class_DateTimeImmutable_createFromMutable, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
ZEND_ME(DateTimeImmutable, createFromInterface, arginfo_class_DateTimeImmutable_createFromInterface, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
ZEND_FE_END

View File

@ -0,0 +1,197 @@
--TEST--
Tests for DateTime[Immutable]::[get|set]Microseconds
--FILE--
<?php
class MyDateTime extends DateTime {};
class MyDateTimeImmutable extends DateTimeImmutable {};
$microsecondsList = array(
0,
999999,
-1,
1000000
);
$dt = new DateTime('2023-04-05T06:07:08.901234+00:00');
$dti = new DateTimeImmutable('2023-04-05T06:07:08.901234+00:00');
$myDt = new MyDateTime('2023-04-05T06:07:08.901234+00:00');
$myDti = new MyDateTimeImmutable('2023-04-05T06:07:08.901234+00:00');
echo 'DateTime::getMicroseconds(): ' . var_export($dt->getMicroseconds(), true) . "\n";
var_dump($dt);
echo 'DateTimeImmutable::getMicroseconds(): ' . var_export($dti->getMicroseconds(), true) . "\n";
var_dump($dti);
echo 'MyDateTime::getMicroseconds(): ' . var_export($myDt->getMicroseconds(), true) . "\n";
var_dump($myDt);
echo 'MyDateTimeImmutable::getMicroseconds(): ' . var_export($myDti->getMicroseconds(), true) . "\n";
var_dump($myDti);
foreach ($microsecondsList as $microseconds) {
echo "##################################\n";
echo 'DateTime::setMicroseconds('.var_export($microseconds, true).'): ';
try {
var_dump($dt->setMicroseconds($microseconds));
} catch (Throwable $e) {
echo get_class($e) . ': ' . $e->getMessage() . "\n";
}
echo 'DateTime::getMicroseconds(): ' . var_export($dt->getMicroseconds(), true) . "\n";
echo 'DateTimeImmutable::setMicroseconds('.var_export($microseconds, true).'): ';
try {
var_dump($dti->setMicroseconds($microseconds));
} catch (Throwable $e) {
echo get_class($e) . ': ' . $e->getMessage() . "\n";
}
echo 'DateTimeImmutable::getMicroseconds(): ' . var_export($dti->getMicroseconds(), true) . "\n";
echo 'MyDateTime::setMicroseconds('.var_export($microseconds, true).'): ';
try {
var_dump($myDt->setMicroseconds($microseconds));
} catch (Throwable $e) {
echo get_class($e) . ': ' . $e->getMessage() . "\n";
}
echo 'MyDateTime::getMicroseconds(): ' . var_export($myDt->getMicroseconds(), true) . "\n";
echo 'MyDateTimeImmutable::setMicroseconds('.var_export($microseconds, true).'): ';
try {
var_dump($myDti->setMicroseconds($microseconds));
} catch (Throwable $e) {
echo get_class($e) . ': ' . $e->getMessage() . "\n";
}
echo 'MyDateTimeImmutable::getMicroseconds(): ' . var_export($myDti->getMicroseconds(), true) . "\n";
}
?>
--EXPECTF--
DateTime::getMicroseconds(): 901234
object(DateTime)#%d (3) {
["date"]=>
string(26) "2023-04-05 06:07:08.901234"
["timezone_type"]=>
int(1)
["timezone"]=>
string(6) "+00:00"
}
DateTimeImmutable::getMicroseconds(): 901234
object(DateTimeImmutable)#%d (3) {
["date"]=>
string(26) "2023-04-05 06:07:08.901234"
["timezone_type"]=>
int(1)
["timezone"]=>
string(6) "+00:00"
}
MyDateTime::getMicroseconds(): 901234
object(MyDateTime)#%d (3) {
["date"]=>
string(26) "2023-04-05 06:07:08.901234"
["timezone_type"]=>
int(1)
["timezone"]=>
string(6) "+00:00"
}
MyDateTimeImmutable::getMicroseconds(): 901234
object(MyDateTimeImmutable)#%d (3) {
["date"]=>
string(26) "2023-04-05 06:07:08.901234"
["timezone_type"]=>
int(1)
["timezone"]=>
string(6) "+00:00"
}
##################################
DateTime::setMicroseconds(0): object(DateTime)#%d (3) {
["date"]=>
string(26) "2023-04-05 06:07:08.000000"
["timezone_type"]=>
int(1)
["timezone"]=>
string(6) "+00:00"
}
DateTime::getMicroseconds(): 0
DateTimeImmutable::setMicroseconds(0): object(DateTimeImmutable)#%d (3) {
["date"]=>
string(26) "2023-04-05 06:07:08.000000"
["timezone_type"]=>
int(1)
["timezone"]=>
string(6) "+00:00"
}
DateTimeImmutable::getMicroseconds(): 901234
MyDateTime::setMicroseconds(0): object(MyDateTime)#%d (3) {
["date"]=>
string(26) "2023-04-05 06:07:08.000000"
["timezone_type"]=>
int(1)
["timezone"]=>
string(6) "+00:00"
}
MyDateTime::getMicroseconds(): 0
MyDateTimeImmutable::setMicroseconds(0): object(MyDateTimeImmutable)#%d (3) {
["date"]=>
string(26) "2023-04-05 06:07:08.000000"
["timezone_type"]=>
int(1)
["timezone"]=>
string(6) "+00:00"
}
MyDateTimeImmutable::getMicroseconds(): 901234
##################################
DateTime::setMicroseconds(999999): object(DateTime)#%d (3) {
["date"]=>
string(26) "2023-04-05 06:07:08.999999"
["timezone_type"]=>
int(1)
["timezone"]=>
string(6) "+00:00"
}
DateTime::getMicroseconds(): 999999
DateTimeImmutable::setMicroseconds(999999): object(DateTimeImmutable)#%d (3) {
["date"]=>
string(26) "2023-04-05 06:07:08.999999"
["timezone_type"]=>
int(1)
["timezone"]=>
string(6) "+00:00"
}
DateTimeImmutable::getMicroseconds(): 901234
MyDateTime::setMicroseconds(999999): object(MyDateTime)#%d (3) {
["date"]=>
string(26) "2023-04-05 06:07:08.999999"
["timezone_type"]=>
int(1)
["timezone"]=>
string(6) "+00:00"
}
MyDateTime::getMicroseconds(): 999999
MyDateTimeImmutable::setMicroseconds(999999): object(MyDateTimeImmutable)#%d (3) {
["date"]=>
string(26) "2023-04-05 06:07:08.999999"
["timezone_type"]=>
int(1)
["timezone"]=>
string(6) "+00:00"
}
MyDateTimeImmutable::getMicroseconds(): 901234
##################################
DateTime::setMicroseconds(-1): DateRangeError: DateTime::setMicroseconds(): Argument #1 ($microseconds) must be between 0 and 999999, -1 given
DateTime::getMicroseconds(): 999999
DateTimeImmutable::setMicroseconds(-1): DateRangeError: DateTimeImmutable::setMicroseconds(): Argument #1 ($microseconds) must be between 0 and 999999, -1 given
DateTimeImmutable::getMicroseconds(): 901234
MyDateTime::setMicroseconds(-1): DateRangeError: DateTime::setMicroseconds(): Argument #1 ($microseconds) must be between 0 and 999999, -1 given
MyDateTime::getMicroseconds(): 999999
MyDateTimeImmutable::setMicroseconds(-1): DateRangeError: DateTimeImmutable::setMicroseconds(): Argument #1 ($microseconds) must be between 0 and 999999, -1 given
MyDateTimeImmutable::getMicroseconds(): 901234
##################################
DateTime::setMicroseconds(1000000): DateRangeError: DateTime::setMicroseconds(): Argument #1 ($microseconds) must be between 0 and 999999, 1000000 given
DateTime::getMicroseconds(): 999999
DateTimeImmutable::setMicroseconds(1000000): DateRangeError: DateTimeImmutable::setMicroseconds(): Argument #1 ($microseconds) must be between 0 and 999999, 1000000 given
DateTimeImmutable::getMicroseconds(): 901234
MyDateTime::setMicroseconds(1000000): DateRangeError: DateTime::setMicroseconds(): Argument #1 ($microseconds) must be between 0 and 999999, 1000000 given
MyDateTime::getMicroseconds(): 999999
MyDateTimeImmutable::setMicroseconds(1000000): DateRangeError: DateTimeImmutable::setMicroseconds(): Argument #1 ($microseconds) must be between 0 and 999999, 1000000 given
MyDateTimeImmutable::getMicroseconds(): 901234