Hi !
Sorry derick for the duplicated email but I was not registered.
This is my first contribution, so I would appreciate any help on the
proposal and on following the project's contribution process.
I opened issue #23491 for a possible addition to ext/date:
https://github.com/php/php-src/issues/23491
I would appreciate feedback before preparing an implementation.
PHP currently provides DATE_RFC3339_EXTENDED, which includes millisecond
precision. For a UTC DateTime, it produces:
1970-01-01T00:00:00.000+00:00
Some applications need the equivalent representation with the ISO 8601 UTC
designator Z:
1970-01-01T00:00:00.000Z
This is also the format produced by JavaScript's
Date.prototype.toISOString():
new Date(0).toISOString();
// "1970-01-01T00:00:00.000Z"
Would a predefined format for this representation be appropriate for
ext/date?
One possible API would be:
DATE_ISO8601_MILLISECONDS_UTC
DateTimeInterface::ISO8601_MILLISECONDS_UTC
with the format string:
"Y-m-d\\TH:i:s.v\\Z"
For example:
$date = new DateTimeImmutable('@0');
echo $date->setTimezone(new DateTimeZone('UTC'))
->format(DATE_ISO8601_MILLISECONDS_UTC);
// 1970-01-01T00:00:00.000Z
The name and API shape are open for discussion. Another option would be an
offset-preserving format:
DATE_ISO8601_MILLISECONDS
DateTimeInterface::ISO8601_MILLISECONDS
using:
"Y-m-d\\TH:i:s.vP"
I understand that date format constants only define formatting; they do not
change the timezone of the DateTime object.
A format containing a literal Z would therefore require the caller to
normalize the object to UTC first.
For context, issue #14593 discusses the interpretation of the Z suffix when
parsing DateTime values:
https://github.com/php/php-src/issues/14593
That issue concerns parsing and timezone representation, whereas this
proposal concerns predefined formatting constants.
I would appreciate feedback on:
- Whether a millisecond-precision format is useful in addition to
DATE_RFC3339_EXTENDED. - Whether an offset-preserving format or a UTC-suffix format is preferable.
- Whether the proposed names follow the preferred ext/date convention.
- Whether an RFC is required before implementation.
Thank you,
Théo Attali
Hey Théo
Hi !
Sorry derick for the duplicated email but I was not registered.
This is my first contribution, so I would appreciate any help on the
proposal and on following the project's contribution process.I opened issue #23491 for a possible addition to ext/date:
https://github.com/php/php-src/issues/23491I would appreciate feedback before preparing an implementation.
PHP currently provides DATE_RFC3339_EXTENDED, which includes millisecond
precision. For a UTC DateTime, it produces:1970-01-01T00:00:00.000+00:00Some applications need the equivalent representation with the ISO 8601 UTC
designator Z:1970-01-01T00:00:00.000ZThis is also the format produced by JavaScript's
Date.prototype.toISOString():new Date(0).toISOString(); // "1970-01-01T00:00:00.000Z"Would a predefined format for this representation be appropriate for
ext/date?One possible API would be:
DATE_ISO8601_MILLISECONDS_UTC DateTimeInterface::ISO8601_MILLISECONDS_UTCwith the format string:
"Y-m-d\\TH:i:s.v\\Z"For example:
$date = new DateTimeImmutable('@0'); echo $date->setTimezone(new DateTimeZone('UTC')) ->format(DATE_ISO8601_MILLISECONDS_UTC); // 1970-01-01T00:00:00.000ZThe name and API shape are open for discussion. Another option would be an
offset-preserving format:DATE_ISO8601_MILLISECONDS DateTimeInterface::ISO8601_MILLISECONDSusing:
"Y-m-d\\TH:i:s.vP"I understand that date format constants only define formatting; they do not
change the timezone of the DateTime object.
A format containing a literal Z would therefore require the caller to
normalize the object to UTC first.For context, issue #14593 discusses the interpretation of the Z suffix when
parsing DateTime values:https://github.com/php/php-src/issues/14593That issue concerns parsing and timezone representation, whereas this
proposal concerns predefined formatting constants.I would appreciate feedback on:
- Whether a millisecond-precision format is useful in addition to
DATE_RFC3339_EXTENDED.- Whether an offset-preserving format or a UTC-suffix format is preferable.
- Whether the proposed names follow the preferred ext/date convention.
- Whether an RFC is required before implementation.
Thank you,
Théo Attali
I see some serious issues with the idea of adding the format with the
\\Z at the end as you already described. It would require a
prerequisite that can'T be enforced and that will therefore cause a lot
of confusion.
To ease that confusion I would recommend anyone that has that explicit
requirement to create a Formatter - perhaps tehr eeven is one already
available that in essence just does something like this:
class Formatter
{
public static function formatIso(DateTimeImmutable $date): string
{
return $date->setTimezone(new
DateTimeZone('UTC'))->format('Y-m-d\TH:i:s.vP');
}
}
Maintaining such a set of Formatters in Userland seems to be much easier
than adding that in the PHP-Src. It would also make the formatter
available to ALL PHP-Versions that have a DateTimeImmutable object and
not only PHP8.6/8.7 onwards.
From my side I would by now not add any more constants to the
PHP-Source as they will not be available to earler versions. And I say
that as the person that added the _EXTENDED constants...
By now I would create a formatter in userland and promote that for usage
as it's a small library that can be used by any PHP-Version that needs
it.
My 0.02€
Cheers
Andreas
,,,
(o o)
+---------------------------------------------------------ooO-(_)-Ooo-+
| Andreas Heigl |
| mailto:andreas@heigl.org N 50°22'59.5" E 08°23'58" |
| https://andreas.heigl.org |
+---------------------------------------------------------------------+
| https://hei.gl/appointmentwithandreas |
+---------------------------------------------------------------------+
| GPG-Key: https://hei.gl/keyandreasheiglorg |
+---------------------------------------------------------------------+
Hi Andreas,
Thank you for your feedback.
I agree that a format constant containing a literal Z is not ideal because
the format string cannot enforce UTC. A userland formatter is safer because
it can normalize the value before formatting it.
After considering this, I think an instance method may be a better fit than
a new format constant:
$date->toISOString();
The method could normalize the instant to UTC and return exactly:
1970-01-01T00:00:00.000Z
It would not modify the original object, which is particularly important for
DateTimeImmutable.
I also found that Carbon provides:
$date->toIso8601ZuluString('millisecond');
However, that requires an external dependency. My motivation is to provide
a dependency-free way to produce a common ISO 8601 UTC representation used
when exchanging timestamps between PHP, JavaScript, Java, Go, and other
ecosystems.
I searched for an existing PHP issue or RFC proposing this exact method but
found only the older, inactive DateTime::__toString() RFC, which addressed
a different problem.
Would you consider a UTC-normalizing instance method a more appropriate
direction for this issue than adding a format constant?
Best regards,
Théo Attali
El sáb, 29 ago 2026 a las 12:36, Andreas Heigl (andreas@heigl.org)
escribió:
Hey Théo
Hi !
Sorry derick for the duplicated email but I was not registered.
This is my first contribution, so I would appreciate any help on the
proposal and on following the project's contribution process.I opened issue #23491 for a possible addition to ext/date:
https://github.com/php/php-src/issues/23491I would appreciate feedback before preparing an implementation.
PHP currently provides DATE_RFC3339_EXTENDED, which includes millisecond
precision. For a UTC DateTime, it produces:1970-01-01T00:00:00.000+00:00Some applications need the equivalent representation with the ISO 8601
UTC
designator Z:1970-01-01T00:00:00.000ZThis is also the format produced by JavaScript's
Date.prototype.toISOString():new Date(0).toISOString(); // "1970-01-01T00:00:00.000Z"Would a predefined format for this representation be appropriate for
ext/date?One possible API would be:
DATE_ISO8601_MILLISECONDS_UTC DateTimeInterface::ISO8601_MILLISECONDS_UTCwith the format string:
"Y-m-d\\TH:i:s.v\\Z"For example:
$date = new DateTimeImmutable('@0'); echo $date->setTimezone(new DateTimeZone('UTC')) ->format(DATE_ISO8601_MILLISECONDS_UTC); // 1970-01-01T00:00:00.000ZThe name and API shape are open for discussion. Another option would be
an
offset-preserving format:DATE_ISO8601_MILLISECONDS DateTimeInterface::ISO8601_MILLISECONDSusing:
"Y-m-d\\TH:i:s.vP"I understand that date format constants only define formatting; they do
not
change the timezone of the DateTime object.
A format containing a literal Z would therefore require the caller to
normalize the object to UTC first.For context, issue #14593 discusses the interpretation of the Z suffix
when
parsing DateTime values:https://github.com/php/php-src/issues/14593That issue concerns parsing and timezone representation, whereas this
proposal concerns predefined formatting constants.I would appreciate feedback on:
- Whether a millisecond-precision format is useful in addition to
DATE_RFC3339_EXTENDED.- Whether an offset-preserving format or a UTC-suffix format is
preferable.- Whether the proposed names follow the preferred ext/date convention.
- Whether an RFC is required before implementation.
Thank you,
Théo Attali
I see some serious issues with the idea of adding the format with the
\\Zat the end as you already described. It would require a
prerequisite that can'T be enforced and that will therefore cause a lot
of confusion.To ease that confusion I would recommend anyone that has that explicit
requirement to create a Formatter - perhaps tehr eeven is one already
available that in essence just does something like this:class Formatter
{
public static function formatIso(DateTimeImmutable $date): string
{
return $date->setTimezone(new
DateTimeZone('UTC'))->format('Y-m-d\TH:i:s.vP');
}
}Maintaining such a set of Formatters in Userland seems to be much easier
than adding that in the PHP-Src. It would also make the formatter
available to ALL PHP-Versions that have a DateTimeImmutable object and
not only PHP8.6/8.7 onwards.From my side I would by now not add any more constants to the
PHP-Source as they will not be available to earler versions. And I say
that as the person that added the _EXTENDED constants...By now I would create a formatter in userland and promote that for usage
as it's a small library that can be used by any PHP-Version that needs
it.My 0.02€
Cheers
Andreas
,,, (o o)+---------------------------------------------------------ooO-(_)-Ooo-+
| Andreas Heigl |
| mailto:andreas@heigl.org N 50°22'59.5" E 08°23'58" |
| https://andreas.heigl.org |
+---------------------------------------------------------------------+
| https://hei.gl/appointmentwithandreas |
+---------------------------------------------------------------------+
| GPG-Key: https://hei.gl/keyandreasheiglorg |
+---------------------------------------------------------------------+
Hey Théo
Hi Andreas,
Thank you for your feedback.
I agree that a format constant containing a literal Z is not ideal because
the format string cannot enforce UTC. A userland formatter is safer because
it can normalize the value before formatting it.After considering this, I think an instance method may be a better fit than
a new format constant:$date->toISOString();The method could normalize the instant to UTC and return exactly:
1970-01-01T00:00:00.000ZIt would not modify the original object, which is particularly important for
DateTimeImmutable.I also found that Carbon provides:
$date->toIso8601ZuluString('millisecond');However, that requires an external dependency. My motivation is to provide
a dependency-free way to produce a common ISO 8601 UTC representation used
when exchanging timestamps between PHP, JavaScript, Java, Go, and other
ecosystems.I searched for an existing PHP issue or RFC proposing this exact method but
found only the older, inactive DateTime::__toString() RFC, which addressed
a different problem.Would you consider a UTC-normalizing instance method a more appropriate
direction for this issue than adding a format constant?
Well... PHP already has a dependency-free way to format any
datetime-object into an ISO string:
echo $anyDateTimeImmutable
->setTimezone(new DateTimeZone('UTC'))
->format('Y-m-d\TH:i:s.vP');
If you want to avoid having to write that string all the time, feel free
to do something like
Interface IsoDateTime
{
const WITH_MILLISECONDS = 'Y-m-d\TH:i:s.vP';
const JUST_SECONDS = 'Y-m-d\\TH:i:sP';
}
and then call
echo $anyDateTimeImmutable
->setTimezone(new DateTimeZone('UTC'))
->format(IsoDateTimeInterface::WITH_MILLISECONDS);
That works since PHP5.3
Anything else is adding convenience at a cost.
And for me (but I am just one person here on the list) that cost
(limited availability to older versions, increasingly polluted
constants, very specific use-case, possibly broken output due to wrong
timezone) outweighs the benfits.
Just my 0.02€
Cheers
Andreas
Best regards,
Théo Attali
El sáb, 29 ago 2026 a las 12:36, Andreas Heigl (andreas@heigl.org)
escribió:Hey Théo
Hi !
Sorry derick for the duplicated email but I was not registered.
This is my first contribution, so I would appreciate any help on the
proposal and on following the project's contribution process.I opened issue #23491 for a possible addition to ext/date:
https://github.com/php/php-src/issues/23491I would appreciate feedback before preparing an implementation.
PHP currently provides DATE_RFC3339_EXTENDED, which includes millisecond
precision. For a UTC DateTime, it produces:1970-01-01T00:00:00.000+00:00Some applications need the equivalent representation with the ISO 8601
UTC
designator Z:1970-01-01T00:00:00.000ZThis is also the format produced by JavaScript's
Date.prototype.toISOString():new Date(0).toISOString(); // "1970-01-01T00:00:00.000Z"Would a predefined format for this representation be appropriate for
ext/date?One possible API would be:
DATE_ISO8601_MILLISECONDS_UTC DateTimeInterface::ISO8601_MILLISECONDS_UTCwith the format string:
"Y-m-d\\TH:i:s.v\\Z"For example:
$date = new DateTimeImmutable('@0'); echo $date->setTimezone(new DateTimeZone('UTC')) ->format(DATE_ISO8601_MILLISECONDS_UTC); // 1970-01-01T00:00:00.000ZThe name and API shape are open for discussion. Another option would be
an
offset-preserving format:DATE_ISO8601_MILLISECONDS DateTimeInterface::ISO8601_MILLISECONDSusing:
"Y-m-d\\TH:i:s.vP"I understand that date format constants only define formatting; they do
not
change the timezone of the DateTime object.
A format containing a literal Z would therefore require the caller to
normalize the object to UTC first.For context, issue #14593 discusses the interpretation of the Z suffix
when
parsing DateTime values:https://github.com/php/php-src/issues/14593That issue concerns parsing and timezone representation, whereas this
proposal concerns predefined formatting constants.I would appreciate feedback on:
- Whether a millisecond-precision format is useful in addition to
DATE_RFC3339_EXTENDED.- Whether an offset-preserving format or a UTC-suffix format is
preferable.- Whether the proposed names follow the preferred ext/date convention.
- Whether an RFC is required before implementation.
Thank you,
Théo Attali
I see some serious issues with the idea of adding the format with the
\\Zat the end as you already described. It would require a
prerequisite that can'T be enforced and that will therefore cause a lot
of confusion.To ease that confusion I would recommend anyone that has that explicit
requirement to create a Formatter - perhaps tehr eeven is one already
available that in essence just does something like this:class Formatter
{
public static function formatIso(DateTimeImmutable $date): string
{
return $date->setTimezone(new
DateTimeZone('UTC'))->format('Y-m-d\TH:i:s.vP');
}
}Maintaining such a set of Formatters in Userland seems to be much easier
than adding that in the PHP-Src. It would also make the formatter
available to ALL PHP-Versions that have a DateTimeImmutable object and
not only PHP8.6/8.7 onwards.From my side I would by now not add any more constants to the
PHP-Source as they will not be available to earler versions. And I say
that as the person that added the _EXTENDED constants...By now I would create a formatter in userland and promote that for usage
as it's a small library that can be used by any PHP-Version that needs
it.My 0.02€
Cheers
Andreas
,,, (o o)+---------------------------------------------------------ooO-(_)-Ooo-+
| Andreas Heigl |
| mailto:andreas@heigl.org N 50°22'59.5" E 08°23'58" |
| https://andreas.heigl.org |
+---------------------------------------------------------------------+
| https://hei.gl/appointmentwithandreas |
+---------------------------------------------------------------------+
| GPG-Key: https://hei.gl/keyandreasheiglorg |
+---------------------------------------------------------------------+
--
,,,
(o o)
+---------------------------------------------------------ooO-(_)-Ooo-+
| Andreas Heigl |
| mailto:andreas@heigl.org N 50°22'59.5" E 08°23'58" |
| https://andreas.heigl.org |
+---------------------------------------------------------------------+
| https://hei.gl/appointmentwithandreas |
+---------------------------------------------------------------------+
| GPG-Key: https://hei.gl/keyandreasheiglorg |
+---------------------------------------------------------------------+