Commit 1d397fcd57f for php

commit 1d397fcd57f09f69b515e275723c5d7f269148f8
Author: Tim Düsterhus <tim@tideways-gmbh.com>
Date:   Thu Oct 8 15:02:39 2026 +0200

    date: Add `php_date_time_duration_create()` in a new `time_duration.h` (#24072)

diff --git a/UPGRADING.INTERNALS b/UPGRADING.INTERNALS
index efcf9c00544..2f6ea7d9ea8 100644
--- a/UPGRADING.INTERNALS
+++ b/UPGRADING.INTERNALS
@@ -62,6 +62,10 @@ PHP 8.7 INTERNALS UPGRADE NOTES
 3. Module changes
 ========================

+- Date:
+  . Added php_date_time_duration_create() to create Time\Duration objects
+    without going through the userland API.
+
 - MySQLi:
   . Removed the reverse API. The mysqlnd_reverse_api.h header, the
     MYSQLND_REVERSE_API struct and the functions zval_to_mysqlnd(),
diff --git a/ext/date/php_time.h b/ext/date/php_time.h
index e6bc7658e38..25dfd306280 100644
--- a/ext/date/php_time.h
+++ b/ext/date/php_time.h
@@ -17,32 +17,11 @@
 # define PHP_DATE_TIME_H

 # include "php.h"
-# include "lib/timelib.h"

-typedef struct php_date_time_duration {
-	timelib_duration  duration;
-	zend_object       std;
-} php_date_time_duration;
-
-# define php_date_time_duration_from_obj(obj) ZEND_CONTAINER_OF(obj, php_date_time_duration, std)
-
-# define Z_DATE_TIME_DURATION_P(zv)  php_date_time_duration_from_obj(Z_OBJ_P((zv)))
-
-# define Z_PARAM_DATE_TIME_DURATION(d) { \
-		zend_object *__##d; \
-		Z_PARAM_OBJ_OF_CLASS(__##d, php_date_ce_time_duration); \
-		d = php_date_time_duration_from_obj(__##d); \
-	}
-
-# define Z_PARAM_DATE_TIME_DURATION_OR_NULL(d) { \
-		zend_object *__##d; \
-		Z_PARAM_OBJ_OF_CLASS_OR_NULL(__##d, php_date_ce_time_duration); \
-		d = __##d ? php_date_time_duration_from_obj(__##d) : NULL; \
-	}
+PHP_MINIT_FUNCTION(date_time);

-PHPAPI extern zend_class_entry *php_date_ce_time_duration;
 PHPAPI extern zend_class_entry *php_date_ce_time_timeexception;

-PHP_MINIT_FUNCTION(date_time);
+# include "time_duration.h"

 #endif /* PHP_DATE_TIME_H */
diff --git a/ext/date/time_duration.c b/ext/date/time_duration.c
index 3cbfca85649..239dca36408 100644
--- a/ext/date/time_duration.c
+++ b/ext/date/time_duration.c
@@ -18,6 +18,7 @@

 #include "php_date.h"
 #include "php_time.h"
+#include "time_duration.h"

 #define NANOS_IN_SEC 1000000000
 #define NANOS_IN_MICRO 1000
@@ -113,7 +114,7 @@ ZEND_ATTRIBUTE_NODISCARD static inline zend_result sync_properties(php_date_time
 	return SUCCESS;
 }

-ZEND_ATTRIBUTE_NODISCARD static zend_result create_duration(zval *target, zend_ulong seconds, zend_ulong nanoseconds)
+ZEND_ATTRIBUTE_NODISCARD PHPAPI zend_result php_date_time_duration_create(zval *target, zend_ulong seconds, zend_ulong nanoseconds)
 {
 	ZEND_ASSERT(nanoseconds < NANOS_IN_SEC);

@@ -217,7 +218,7 @@ PHP_METHOD(Time_Duration, fromSeconds)
 		RETURN_THROWS();
 	}

-	if (create_duration(return_value, seconds, nanoseconds) == FAILURE) {
+	if (php_date_time_duration_create(return_value, seconds, nanoseconds) == FAILURE) {
 		RETURN_THROWS();
 	}
 }
@@ -233,7 +234,7 @@ PHP_METHOD(Time_Duration, fromNanoseconds)
 	zend_ulong seconds = nanoseconds / NANOS_IN_SEC;
 	nanoseconds %= NANOS_IN_SEC;

-	if (create_duration(return_value, seconds, nanoseconds) == FAILURE) {
+	if (php_date_time_duration_create(return_value, seconds, nanoseconds) == FAILURE) {
 		RETURN_THROWS();
 	}
 }
@@ -249,7 +250,7 @@ PHP_METHOD(Time_Duration, fromMicroseconds)
 	zend_ulong seconds = microseconds / MICROS_IN_SEC;
 	zend_ulong nanoseconds = (microseconds % MICROS_IN_SEC) * NANOS_IN_MICRO;

-	if (create_duration(return_value, seconds, nanoseconds) == FAILURE) {
+	if (php_date_time_duration_create(return_value, seconds, nanoseconds) == FAILURE) {
 		RETURN_THROWS();
 	}
 }
@@ -265,7 +266,7 @@ PHP_METHOD(Time_Duration, fromMilliseconds)
 	zend_ulong seconds = milliseconds / MILLIS_IN_SEC;
 	zend_ulong nanoseconds = (milliseconds % MILLIS_IN_SEC) * NANOS_IN_MILLI;

-	if (create_duration(return_value, seconds, nanoseconds) == FAILURE) {
+	if (php_date_time_duration_create(return_value, seconds, nanoseconds) == FAILURE) {
 		RETURN_THROWS();
 	}
 }
@@ -283,7 +284,7 @@ PHP_METHOD(Time_Duration, fromMinutes)
 		RETURN_THROWS();
 	}

-	if (create_duration(return_value, minutes * 60, /* nanoseconds */ 0) == FAILURE) {
+	if (php_date_time_duration_create(return_value, minutes * 60, /* nanoseconds */ 0) == FAILURE) {
 		RETURN_THROWS();
 	}
 }
@@ -301,7 +302,7 @@ PHP_METHOD(Time_Duration, fromHours)
 		RETURN_THROWS();
 	}

-	if (create_duration(return_value, hours * 3600, /* nanoseconds */ 0) == FAILURE) {
+	if (php_date_time_duration_create(return_value, hours * 3600, /* nanoseconds */ 0) == FAILURE) {
 		RETURN_THROWS();
 	}
 }
@@ -359,7 +360,7 @@ PHP_METHOD(Time_Duration, absolute)
 		RETURN_COPY(ZEND_THIS);
 	}

-	if (create_duration(return_value, original->duration.seconds, original->duration.nanoseconds) == FAILURE) {
+	if (php_date_time_duration_create(return_value, original->duration.seconds, original->duration.nanoseconds) == FAILURE) {
 		RETURN_THROWS();
 	}
 }
diff --git a/ext/date/time_duration.h b/ext/date/time_duration.h
new file mode 100644
index 00000000000..c7b4e456514
--- /dev/null
+++ b/ext/date/time_duration.h
@@ -0,0 +1,47 @@
+/*
+   +----------------------------------------------------------------------+
+   | Copyright © The PHP Group and Contributors.                          |
+   +----------------------------------------------------------------------+
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at <https://www.php.net/license/>.        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
+   +----------------------------------------------------------------------+
+   | Authors: Derick Rethans <derick@derickrethans.nl>                    |
+   |          Tim Düsterhus <timwolla@php.net>                            |
+   +----------------------------------------------------------------------+
+*/
+
+#ifndef PHP_DATE_TIME_DURATION_H
+# define PHP_DATE_TIME_DURATION_H
+
+# include "php.h"
+# include "lib/timelib.h"
+
+PHPAPI extern zend_class_entry *php_date_ce_time_duration;
+
+typedef struct php_date_time_duration {
+	timelib_duration  duration;
+	zend_object       std;
+} php_date_time_duration;
+
+# define php_date_time_duration_from_obj(obj) ZEND_CONTAINER_OF(obj, php_date_time_duration, std)
+
+# define Z_DATE_TIME_DURATION_P(zv)  php_date_time_duration_from_obj(Z_OBJ_P((zv)))
+
+# define Z_PARAM_DATE_TIME_DURATION(d) { \
+		zend_object *__##d; \
+		Z_PARAM_OBJ_OF_CLASS(__##d, php_date_ce_time_duration); \
+		d = php_date_time_duration_from_obj(__##d); \
+	}
+
+# define Z_PARAM_DATE_TIME_DURATION_OR_NULL(d) { \
+		zend_object *__##d; \
+		Z_PARAM_OBJ_OF_CLASS_OR_NULL(__##d, php_date_ce_time_duration); \
+		d = __##d ? php_date_time_duration_from_obj(__##d) : NULL; \
+	}
+
+ZEND_ATTRIBUTE_NODISCARD PHPAPI zend_result php_date_time_duration_create(zval *target, zend_ulong seconds, zend_ulong nanoseconds);
+
+#endif /* PHP_DATE_TIME_DURATION_H */
diff --git a/ext/standard/io_poll.c b/ext/standard/io_poll.c
index a90a9292bb8..c2585a51d3c 100644
--- a/ext/standard/io_poll.c
+++ b/ext/standard/io_poll.c
@@ -20,7 +20,7 @@
 #include "io_poll.h"
 #include "io_poll_arginfo.h"
 #include "io_poll_decl.h"
-#include "ext/date/php_time.h"
+#include "ext/date/time_duration.h"

 /* Class entries */
 static zend_class_entry *php_io_poll_backend_class_entry;