tc39 / tc39/proposal-temporal

Accurate JSON representation for duration

Open
#3,095 13 comments 4 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

behavior normative
Dominant language
HTML
Stars
3.7k
Forks
177
PR merge metrics
No merged PRs in 30d

Description

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

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reading the Temporal.Duration toJSON, toString, round, and compare behavior described in the issue, then review the linked RFC Internet-Draft and Go interoperability discussions. Done means a documented TC39 decision on whether JSON serialization should round accurate durations and how nominal units are handled.

Written by the indexing model from the issue text.

Assessment

Tech stack
go, java, javascript
Domain
backend-api-design
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.