Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Time unit recommendations and the TC39 Temporal proposal #101

Open
littledan opened this issue Oct 21, 2018 · 8 comments
Open

Time unit recommendations and the TC39 Temporal proposal #101

littledan opened this issue Oct 21, 2018 · 8 comments
Assignees
Labels
Size: big tc39-tracker Issues where TC39 input would be useful

Comments

@littledan
Copy link
Contributor

The JavaScript Temporal proposal adds new date and time types to the web platform, and is at Stage 2 in TC39. If this becomes a standard, should the section of the "Client-side API Design Principles" be updated to recommend their use?

@kenchris
Copy link
Contributor

Seems like a good idea. Let's evaluate it when that happens

@kenchris
Copy link
Contributor

Hi @littledan what is the status of Temporal?

@littledan
Copy link
Contributor Author

@kenchris Temporal is still at Stage 2; we hope to propose it for Stage 3 later this year, but development continues to take longer than we expect. We'll come back to the TAG for another round of design review once the current round of changes has settled down.

@hober
Copy link
Contributor

hober commented May 28, 2020

@littledan okay, thanks! We'll wait for that.

@hober hober self-assigned this Sep 14, 2020
@plinss
Copy link
Member

plinss commented Sep 24, 2020

Currently we recommend DOMTimeStamps, but it would be nice to replace them in Web APIs with an appropriate Temporal object.

The closest I see seems to be Temporal.Absolute, but it's unclear how we could best make the change while maintaining compatibility. Any suggestions?

@cynthia
Copy link
Member

cynthia commented May 13, 2021

This is no longer blocked, since it has advanced to Stage 3.

@jyasskin
Copy link
Contributor

jyasskin commented May 24, 2023

As Temporal gets closer to shipping in web browsers, we should think about how we want to migrate APIs to use it. I think it's fairly clear that we'll add overloads to the operations that currently take a number of milliseconds, and I'd suggest that the new overload type follow Temporal's precedent of usually accepting Temporal-like objects in addition to actual instances of the Temporal types. For example, Temporal.Duration.add() can take an object {hours: 3, seconds: 2} and not just Temporal.Duration.from({hours:3, seconds:2}).

Temporal also treats strings as convertible to several kinds of Temporal objects (e.g. Temporal.Duration.add() again and Temporal.Instant.compare()), and I'm ambivalent about allowing those overloads. WebIDL makes it possible, but my intuition says it's more likely to cause confusion than the object overloads. I'm happy to accept if others' intuition says the opposite, or if someone manages to gather data about it.

@ptomato
Copy link
Contributor

ptomato commented May 31, 2023

I think there are several enhancements that could be done here, either all at once or progressively, depending on how closely you would like to integrate Temporal APIs.

Re. APIs that take DOMHighResTimeStamp

Instant support

  • I'd recommend at a minimum accepting Temporal.Instant objects here, whose data model is a 96-bit integer of nanoseconds since epoch. They are exactly intended to represent a time stamp, so the intention matches well here. Although note that converting an Instant to a DOMHighResTimeStamp involves coarsening due to floating point precision loss.
  • The only Temporal.Instant-like objects are Temporal.ZonedDateTime instances (see below). You can't construct Temporal.Instant from a plain-object property bag. It seems worth considering accepting a ZonedDateTime instance, but see the next section.
  • Temporal.Instant-like strings exist. Examples: 2023-05-31T11:54-07:00 or 20230531T1854Z. due to the inclusion of at least T and + or - in the UTC offset part, these cannot be confused with JS Numbers, so it seems worth considering accepting them. Strings such as these seem likely to be a common serialization format even without Temporal.
  • See ToTemporalInstant for the algorithm used to convert input to Instant.

ZonedDateTime support

  • Temporal.ZonedDateTime's data model is Temporal.Instant plus Temporal.TimeZone plus Temporal.Calendar. So it also represents an exact time stamp, but with the extra information that allows API consumers to get info about the wall-clock time corresponding to the time stamp. A DOMHighResTimeStamp wouldn't use any of this additional information.
  • Temporal.ZonedDateTime is itself an Instant-like object, so it seems like it makes sense to be able to pass one in as a DOMHighResTimeStamp. As the proposal authors, we've been assuming that ZonedDateTime will be the type that most users reach for first, unless they know they need one of the other types.
  • There are ZonedDateTime-like objects that are not Instant-like objects, such as { year: 2023, month: 5, day: 31, hour: 11, minute: 54, timeZone: 'America/Vancouver' }, or { year: 5783, month: 9, day: 11, hour: 18, minute: 54, calendar: 'hebrew', timeZone: 'UTC' }. These would be trickier, but not impossible, to support, for a few reasons:
    • If there's no offset property in the property bag, you have to guess the UTC offset from the time zone. If the date-time properties indicate a skipped or repeated time from a DST shift, then there's ambiguity.
    • The time zone or the calendar might be custom objects, on which methods would have to be called in order to do the conversion of the property bag to a time stamp.
  • ZonedDateTime-like strings are a subset of Instant-like strings. (edit: not quite)

Re. Time measurement with milliseconds

  • You could consider allowing Temporal.Duration instances to be passed to APIs that take a time measurement.
  • Duration has a total() method. You could effectively do the equivalent of duration.total('milliseconds') and get a floating-point number of milliseconds. (Any microseconds and nanoseconds in the Duration would be subject to floating-point loss.)
  • If so, I'd recommend allowing only Duration instances without calendar units (years, months, weeks). Years, months, and weeks require a calendar and a reference time stamp in order to be converted to milliseconds. Whether days require a reference time stamp is debatable — you can say that all days are exactly 24 hours, or you could disallow days because 23-hour and 25-hour days each occur once a year in most time zones with DST. (The total() method will already reject durations with nonzero years, months, and weeks if you don't provide a reference time stamp.)
  • Temporal.Duration-like objects are property bags that look like this: { hours: 1, minutes: 30, seconds: 29, milliseconds: 999, microseconds: 999, nanoseconds: 999 } which would correspond to a floating-point milliseconds number of 5429999.999999. It seems worth considering accepting these.
  • Temporal.Duration-like strings look like this: PT1H30M29.999999999S. This is a notation from ISO 8601 that is not nearly as well known as the date-time format. Still, for consistency it seems at least worth considering accepting this kind of string.
  • ToTemporalDuration does the conversion from various inputs to a Duration instance.

Design principles for new APIs

Talking about APIs that don't exist yet, as an author of the proposal I'd love to see a recommendation to use Temporal types, but obviously I'm biased.

The current text,

DOMHighResTimeStamp allows comparison of timestamps, regardless of the user’s time settings.

might need to be updated a bit. The existing situation was that Date didn't allow comparison of either time stamps or wall-clock times, because it stores a number of epoch milliseconds which either does or doesn't need to have a UTC offset added to it depending on which method you are calling! (e.g. getHours() vs getUTCHours().) Temporal types don't have this problem: for example, Temporal.PlainDateTime allows comparison of wall-clock times regardless of the user's time settings.

It would be nice to have some recommendations for the case of exact vs. wall-clock times, and for what to do in the case of intentionally missing data.

As an example of the former case, DOMHighResTimeStamp isn't a good way to express a wall-clock time since converting a time stamp to a wall-clock time requires time zone information, so Temporal.PlainDateTime might be appropriate to return from such an API.

As an example of missing data, a date picker might return a date without a time. It might be appropriate to recommend returning a Temporal.PlainDate from such an API (rather than a PlainDateTime, Instant, or DOMHighResTimeStamp set to midnight on that date, which is a common source of bugs with Date.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Size: big tc39-tracker Issues where TC39 input would be useful
Projects
None yet
Development

No branches or pull requests

8 participants