Skip to content

Accurate JSON representation for duration #3095

Open
@dsnet

Description

@dsnet

Hello, thank you for all your hard work improving time support in ECMAScript.

I'm one of the maintainers of the "encoding/json" package in Go, where the community is currently pursuing a prospective "encoding/json/v2" package (golang/go#71497). There's an unsettled debate (golang/go#71631) regarding what the right JSON representation for a Go time.Duration should be, where the community is split between a custom Go representation (e.g., 123h4m56.789s) versus a subset of ISO 8601 (e.g., PT123H4M56.789S). Since JSON is often used as a format for interacting with systems written in other languages, there's value in being consistent with what other implementations support. Furthermore, JSON finds its heritage in JavaScript, so the precedence set by JavaScript does impact the rest of the industry.

While ISO 8601 specifies a set of grammars for a duration, it is unfortunately ill-suited for Go since it supports both nominal units (e.g., year, month, week, day) and accurate units (hour, minute, second). For implementations with duration data structures that represent both nominal and accurate units individually (e.g., Temporal.Duration), this is perfectly fine. However, for languages that can only represent accurate durations, this is impossible to fully support (e.g., Go's time.Duration, java.time.Duration, google.protobuf.Duration, etc.).

Given the existence of many implementations that can only represent accurate durations, I suspect this has significantly impeded the adoption of the ISO 8601 duration format since interoperability is poor if nominal units are ever used. In an attempt remedy this problem, we authored an RFC Internet-Draft that proposes a strict subset of ISO 8601 that prioritizes interoperability. This RFC I-D is merely a proposal intended to kickstart discussion and the grammar is subject to change based on feedback.

The goal of this issue is to raise the concern of interopability and see if we can cooperatively move towards greater interopability. The Internet is comprised of many systems written by many different languages and would benefit from this endeavor.

Overall, it seems the TC39's design is almost entirely compatible with the proposed RFC I-D, but a minor thought we can consider:

  • Have the Temporal.Duration.toJSON method call round({largestUnit: "hour"}) before formatting as ISO 8601 if all the nominal units are zero. This does mean that formatting and parsing from JSON does not round-trip identically, but the Temporal.Duration.compare method does correctly treat PT90S and PT1M30S as equal. One advantage of always rounding is that it avoids leaking details about the fact that Temporal.Duration is able to handle each unit independently (which other languages cannot do). I believe always rounding by the largest hour would make the output compliant with the proposed RFC I-D.

  • The above suggestion is however impossible if nominal units are non-zero. In such a case, the toJSON method would have to output an ISO 8601 duration that may not be parsable by other implementations, but this is the best that can be done when lacking any "reference point". Fortunately, the arguably most common way to obtain a duration is by measuring the passage of time through the use of zonedDateTime.until (or since) methods. The until method defaults to measuring time in terms of accurate units (e.g., up to hours if no options are specified). Thus, I suspect that most common usages of the Temporal types will only have accurate units unless the programmer went out of their way to use nominal units.

  • The above suggestions are targeted toward toJSON, while toString remains unchanged. The assumption is that toJSON is targeted towards machine consumption where accuracy and interopability is a priority, while toString is targeted towards human consumption where readability is a priority.

  • It is far more important that the formatted durations be interoperable (especially in JSON). If Temporal.Duration is able to parse the durations according to the full grammar of ISO 8601, then more power to ECMAScript!

Thank you for considering our thoughts.

\cc @timbray @mvdan @johanbrandhorst

Metadata

Metadata

Assignees

No one assigned

    Labels

    behaviorRelating to behavior defined in the proposalmeeting-agendanormativeWould be a normative change to the proposal

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions