Skip to content

Add a UTC-normalizing DateTime method for ISO 8601 output #23491

Description

@tattali

Update: Based on feedback, this proposal no longer focuses on adding a
format constant. The preferred direction under discussion is a method that
normalizes the represented instant to UTC and returns ISO 8601 output with
millisecond precision and a Z suffix. Check this comment : #23491 (comment)

Description

PHP provides predefined date format constants such as DATE_ISO8601,
DATE_ATOM, DATE_RFC3339, and DATE_RFC3339_EXTENDED. There is no predefined
format for the UTC timestamp commonly produced by JavaScript:

1970-01-01T00:00:00.000Z

For example:

new Date(0).toISOString();
// "1970-01-01T00:00:00.000Z"

Proposal

Add a predefined format for ISO 8601 timestamps with millisecond precision.

One possible name is:

DATE_ISO8601_MILLISECONDS_UTC
DateTimeInterface::ISO8601_MILLISECONDS_UTC

with the format string:

"Y-m-d\\TH:i:s.v\\Z"

The name and API shape are open for discussion.

An alternative is an offset-preserving format:

DATE_ISO8601_MILLISECONDS
DateTimeInterface::ISO8601_MILLISECONDS

using:

"Y-m-d\\TH:i:s.vP"

Example

$date = new DateTimeImmutable('@0');

echo $date->setTimezone(new DateTimeZone('UTC'))
    ->format(DATE_ISO8601_MILLISECONDS_UTC);

// 1970-01-01T00:00:00.000Z

As with the existing date format constants, formatting does not change the
timezone of the DateTime object. The caller must convert it to UTC before
using the _UTC format.

Existing constant

DATE_RFC3339_EXTENDED already includes milliseconds, but produces an offset:

1970-01-01T00:00:00.000+00:00

This is semantically equivalent to Z for UTC, but is not byte-for-byte
compatible with JavaScript's Date.prototype.toISOString().

Related discussion

PHP issue #14593 discusses the
interpretation of the Z suffix when parsing DateTime values. That issue is
about parsing and timezone representation; this proposal is about predefined
formatting constants in ext/date.

Questions

  • Is a millisecond-precision constant useful in addition to
    DATE_RFC3339_EXTENDED?
  • Should the format preserve the object's offset, or provide the Z form for
    UTC-normalized values?
  • What name and API shape should be used?
  • Would both forms introduce unnecessary overlap with the existing constants?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions