Re: [PHP-DEV] Add ISO 8601 date format constant with millisecond precision
Théo Attali <[email protected]>
| Newsgroups | gmane.comp.php.devel |
|---|---|
| Message-ID | <CAF=rBtsw6Atqb6BJNWPbwByiC+KJPmZKiPrYA5qCg7z=07at6Q@mail.gmail.com> |
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 (<[email protected]>)
escribió:
> Hey Théo
>
> On 29.08.26 11:47, Théo Attali wrote:
> > 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:
> >
> > 1. Whether a millisecond-precision format is useful in addition to
> > DATE_RFC3339_EXTENDED.
> > 2. Whether an offset-preserving format or a UTC-suffix format is
> preferable.
> > 3. Whether the proposed names follow the preferred ext/date convention.
> > 4. 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:[email protected] N 50°22'59.5" E 08°23'58" |
> | https://andreas.heigl.org |
> +---------------------------------------------------------------------+
> | https://hei.gl/appointmentwithandreas |
> +---------------------------------------------------------------------+
> | GPG-Key: https://hei.gl/keyandreasheiglorg |
> +---------------------------------------------------------------------+
>
>