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

Temporal proposal #311

Closed
3 of 5 tasks
littledan opened this issue Oct 27, 2018 · 24 comments
Closed
3 of 5 tasks

Temporal proposal #311

littledan opened this issue Oct 27, 2018 · 24 comments
Assignees
Labels
Progress: review complete Review type: later review Topic: scripting ECMA, Web Assembly bindings, etc. Topic: universal JavaScript Features that work on the web and non-web (e.g. node.js) Venue: TC39

Comments

@littledan
Copy link

Bonjour TAG,

I'm requesting a TAG review of:

Further details (optional):

  • Relevant time constraints or deadlines: Feedback is requested before this feature is proposed for Stage 3. We don't have a solid timeline for proposing for Stage 3, but the soonest possible time would be in the January 2019 meeting (and likely later).
  • I have read and filled out the Self-Review Questionnare on Security and Privacy. The answer to all questions is "no"--the only possible security-related concern was related to the possibility of adding more precise Date.now()-like functionality, which this proposal currently omits.
  • I have reviewed the TAG's API Design Principles

You should also know that...

It would be helpful to get feedback on which date/time units are useful/needed for web APIs (e.g., this proposal omits a duration type). The date/time types here may enable changes in the TAG's API Design Principles, c.f., w3ctag/design-principles#101

We'd prefer the TAG provide feedback as (please select one):

  • open issues in our Github repo for each point of feedback
  • open a single issue in our Github repo for the entire review
  • leave review feedback as a comment in this issue and @-notify [github usernames]
@torgo torgo changed the title Tag Review Request: Temporal proposal Temporal proposal Oct 30, 2018
@travisleithead travisleithead self-assigned this Oct 30, 2018
@plinss plinss self-assigned this Oct 30, 2018
@cynthia cynthia self-assigned this Oct 31, 2018
@slightlyoff
Copy link
Member

Stream of consciousness before we take this up properly:

  • Is there a way to represent a time delta in this API?
  • What is the type relationship between Instant and DOMHighResTimeStamp/DOMTimeStamp? Do you envision those DOM types subclassing the new ones? Should they be convertable? Has there been a dicsussion about how IDL will translate them?
  • Has TC39 thought about HTMLTimeElement integration? Or how this can work with <input type="time">?
  • I don't think anyone is happy with the current processing model in HTML which is Gregorian-only (uggh) and which seems to include custom parsers. We'd love your thoughts on how to join these up.
  • Instant's constructor appears to rely on BigInt. Does DOM integration for Instant and related classes require WebIDL extensions?

@slightlyoff slightlyoff self-assigned this Oct 31, 2018
@annevk
Copy link
Member

annevk commented Oct 31, 2018

What is wrong with Gregorian-only for non-user-facing date handling?

@cynthia
Copy link
Member

cynthia commented Oct 31, 2018

Is there a way to represent a time delta in this API?

I was wondering the same.

@littledan
Copy link
Author

Does DOM integration for Instant and related classes require WebIDL extensions?

I have a PR out for review at WebIDL to add BigInt support, but it's waiting for use cases to be articulated. I'm not sure if we'd need BigInt in WebIDL just to support Instant being used in DOM, though.

Is there a way to represent a time delta in this API?

Could you say more about use cases for a time delta representation?

@cynthia
Copy link
Member

cynthia commented Oct 31, 2018

Example would be something like this:

if (date1 - date2 > date3 - date4) {
  // do something
}

(Although this proposal doesn't include a operator overloaded syntax, this is just an example of a use case.)

@pipobscure
Copy link

Re: time-delta

This is actually a fair bit more complicated than that. For one thing, the delta depends on TimeZones which may not be available.

So the approach we have chosen for temporal is to be explicit. So for Instant you'd do

if (instant1.milliseconds - instant2.milliseconds > instant3.milliseconds - instant4.milliseconds) {
  // do something
}

If you assume CivilDate then date1 - date2 will never give you a result that can in any way be relied upon to be correct. So being more explicit ensures that the result will actually be what you'd expect.

@pipobscure
Copy link

Re: DOMHighResTimeStamp/DOMTimeStamp

Both of these are defined as floating point values representing milliseconds. That in turn means that while the resolution may be sufficient, the precision may be off.

Again we have opted to be more explicit.

  • Instant.prototype.seconds - the number seconds since epoch
  • Instant.prototype.milliseconds - the number milliseconds since epoch
  • Instant.prototype.microseconds - the bigint microseconds since epoch
  • Instant.prototype.nanoseconds - the bigint nanoseconds since epoch

Being explicit and using BigInt where relevant ensures that we have both resolution and precision to be correct for calculations.

Using

  • Instant.fromSeconds(seconds : number)
  • Instant.fromMilliseconds(milliseconds : number)
  • Instant.fromMicroseconds(microseconds : bigint)
  • Instant.fromNanoseconds(nanoseconds : bigint)

allows for interoperation.

@pipobscure
Copy link

What is wrong with Gregorian-only for non-user-facing date handling?

Because the Gregorian calendar makes a lot of assumptions that isn't really the case. Think along the lines of days that don't start at midnight. So if you want to do date-calculations, then you have to work in the same calendar as is user-facing, or you are almost guaranteed to get sporadically wrong results.

@annevk
Copy link
Member

annevk commented Oct 31, 2018

That question was in the context of HTML doing something bad, but HTML doesn't do date calculations that I know about.

@mattjohnsonpint
Copy link

Has TC39 thought about HTMLTimeElement integration? Or how this can work with <input type="time">?

Our CivilTime object should map nicely to <input type="time">. Likewise, our CivilDate object should map nicely to <input type="date"> in a way that the current Date object does not.

I previously hadn't looked much at HTMLTimeElement, but on cursory scan, not every data type listed there would have a distinct object in Temporal - at least not with the initial implementation. Using the terminology listed there:

  • ❌ Valid month string
  • ✔️ Valid date string (Temporal CivilDate)
  • ❌ Valid yearless date string
  • ✔️ Valid time string (Temporal CivilTime)
  • ✔️ Valid local date and time string (Temporal CivilDateTime)
  • ❌ Valid time-zone offset string
  • ✔️ Valid global date and time string (Temporal ZonedInstant)
  • ❌ Valid week string
  • ❌ Four or more ASCII digits
  • ❌ Valid duration string

@plinss
Copy link
Member

plinss commented Oct 31, 2018

One thing that would be extremely useful to web apps would be the ability to access the list of IANA time zone names known by the system, possibly as a map with their offsets.

@torgo torgo added this to the 2019-02-05-f2f milestone Feb 5, 2019
@hober
Copy link
Contributor

hober commented Feb 5, 2019

@plinss since the Olson database changes over time, I'm concerned about the fingerprinting implications of exposing the client's known time zone names.

@torgo torgo removed the Paris2018f2f label Feb 5, 2019
@dbaron dbaron self-assigned this Feb 5, 2019
@littledan
Copy link
Author

littledan commented Feb 5, 2019

About the privacy concern, I believe this information can already be inferred through the Intl.DateTimeFormat API.

@littledan
Copy link
Author

About @plinss 's feature request, there was an alternative proposal writeup which would just expose the tz database, rather than including it in a higher level API, and some web authors expressed support for this alternative. We had some discussion in TC39 about a lower-level API in TC39, but decided it was important to unify and provide good tools for high-level usage as well.

@travisleithead travisleithead removed their assignment Feb 7, 2019
@travisleithead
Copy link
Contributor

Took up at Tokyo f2f.

Thanks for the responses so far. As noted by @plinss above, we would really like to see the named time zones provided (if not in this proposal, than in some other venue) to complete the web developer experience of understanding the offsets.

@littledan
Copy link
Author

Thanks for the feedback. I'll investigate whether we can provide this in the TC39 Temporal proposal.

@littledan
Copy link
Author

littledan commented Nov 27, 2020

The Temporal champion group has made several revisions to the proposal based on feedback it's received from the TAG and others. The changes to the proposal are now complete, and now is a good time for final feedback on the documentation and specification before Stage 3 and implementation in browsers.

Some specific comments about the current proposal with respect to the TAG's past feedback:

  • To represent the delta between two Temporal types, we added an explicit Temporal.Duration type, which can also be used in the argument to .plus(). To calculate the difference between two Temporal objects, resulting in a Duration object, use the .since() method that exists on each type.
  • The Civil prefix has been renamed to Plain. Still likely a bit unclear, but it's the best we have. We determined that it's important to have some prefix, to indicate clearly the lack of timezone (as opposed to ZonedDateTime). We plan to edit the documentation to tersely explain this meaning.
  • For the Gregorian-only limitation, we have created a generic calendar API to avoiding being too Gregorian-specific. All dates have calendars attached to them, which govern date arithmetic on them.
  • To get the current timezone, use Temporal.now.timeZone. An API to get the list of all timezones was drafted within the Temporal proposal, but broken out into the Intl Enumeration API, which is currently blocked on investigating this fingerprinting question. Your feedback would be very welcome there.
  • To represent the data model for year-month and month-day date pickers, as well as other use cases, the types Temporal.PlainYearMonth and Temporal.PlainMonthDay were added.

Specifically, about integration with WebIDL and other web specs:

  • WebIDL support for the new bigint type has landed. However, the use in Temporal does not involve WebIDL, as TC39's specifications do not currently use WebIDL.
  • I'm happy to work towards HTML integration whenever it is seen as appropriate by the browsers/HTML editors. Some things already "just work" by coercion to strings (example from the docs).
  • Specifically, for the relationship between DOMHighResTimeStamp and Temporal.Instant: In my opinion, it would be best for future APIs to accept Temporal.Instant, due to its ability to describe higher precision and lack of rounding errors. (Remember not to use it for applications needing a monotonic timer!)
  • I get the feeling that the design philosophy used in web specifications like these is more "demand pull" than "supply push"--even if we have a mechanism which may be useful, we should maybe wait for other specification authors to ask for this integration where it's useful for them. So it seems like the most effective thing would be to publish good documentation about the proposal, rather than push specific integrations on people. This seems to be the philosophy taken about integration about Promise and BigInt integration in Web specifications. (I proposed several BigInt integrations that received a lack of interest for a long time; I don't want to waste people's time with something similar for Temporal.) It seems that the bar for proving that the integration is useful will be high, even amid TAG encouragement.

As an introduction to the current API shape of Temporal, see this presentation which walks through the basic types and operations. Our plan is to integrate this sort of discussion into the Temporal documentation.

@plinss plinss reopened this Nov 28, 2020
@plinss plinss removed the Resolution: satisfied The TAG is satisfied with this design label Dec 7, 2020
littledan added a commit to littledan/html that referenced this issue Jan 13, 2021
This patch lets Temporal objects be serialized, both in storage and with
postMessage, if they use built-in calendars and timezones. This is the
only expected integration of Temporal with HTML/DOM expected initially;
see earlier discussion in w3ctag/design-reviews#311

The current draft just includes Temporal.PlainDate, and it will be extended
to all of the Temporal types after initial review. This patch should not be
landed until (at least) Temporal reaches Stage 3.
@LeaVerou
Copy link
Member

@cynthia, @kenchris, and I discussed this in our VF2F today.

Since there is no explainer but only documentation & the spec, we missed a list of user needs, which would facilitate review.

However, based on the documentation, we are concerned that while powerful, this API is very difficult to use for simpler use cases (see principle of Least Power).

One source of cognitive overhead is the deep hierarchy of objects, the distinction between which is based on what information is available (e.g. day+month vs day+month+year vs month+year or types without a timezone and types with a timezone). Not only does this mean that when objects are constructed based on incremental user input, the developer will need to continuously convert between types, but it also forces the API to promote factory methods for object creation which need to be learned separately, as opposed to constructors. We were wondering about the reasoning behind this decision, compared to a single object, with some of its information undefined or null.

While reviewing, we also spotted a typo in your documentation: in the example here the unit is probably "seconds", not "minutes".

@plinss plinss added the Progress: pending external feedback The TAG is waiting on response to comments/questions asked by the TAG during the review label Feb 14, 2021
@plinss plinss added Progress: propose closing we think it should be closed but are waiting on some feedback or consensus and removed Progress: in progress Progress: pending external feedback The TAG is waiting on response to comments/questions asked by the TAG during the review labels Mar 16, 2021
@cynthia
Copy link
Member

cynthia commented Mar 17, 2021

We discussed what to do about this in today's call - while we have some concerns (as noted above) if the feedback is not actionable we don't think we should block this work. Hopefully there will be some libraries that make this API easier to use for average users. Thanks for bringing this to your attention!

(As for the pattern discussion, we should probably make that a separate discussion on design-principles.)

@cynthia cynthia closed this as completed Mar 17, 2021
@ptomato
Copy link

ptomato commented Mar 23, 2021

Hi TAG! First of all I apologize for not responding sooner. Through my own fault I wasn't subscribed to this thread until two weeks ago, and at that point all my time was taken up with preparing for the TC39 plenary, and later recovering from it. Thanks for taking the time to review the proposal. I have some responses below to Lea's and Sangwhan's messages.

Since there is no explainer but only documentation & the spec, we missed a list of user needs, which would facilitate review.

I've been looking over the requirements for an explainer and while it's true that we don't have a document that follows this format, we did intend our documentation and cookbook to fulfill roughly the same function, of describing the rationale for the proposal, the user needs motivating it, and showing samples of how users would solve problems using it. I'd be interested in hearing more about what was missing from these resources which would have helped with your review, so we can improve this going forward.

One source of cognitive overhead is the deep hierarchy of objects, the distinction between which is based on what information is available (e.g. day+month vs day+month+year vs month+year or types without a timezone and types with a timezone). [...] We were wondering about the reasoning behind this decision, compared to a single object, with some of its information undefined or null.

I can give the rationale for having multiple classes in the proposal. (There is more background in tc39/proposal-temporal#927 and tc39/proposal-temporal#51 if you want to read more about it.) Having strong types is a design decision that was made to avoid bugs that might occur if developers had only one class to work with and had to fill in arbitrary values for missing data, and then decipher what that meant.

For example, "00:00:00" might be a common interpretation of null hour/minute/second fields, but until recently Brazil had their DST transitions at midnight, so for one day every year, that time would not exist, leading to unexpected and hard-to-track-down bugs. The "correct" workaround, to use noon rather than midnight as the missing-time value, is not well-known to most web developers.

In fact the question about HTMLTimeElement integration from the previous review that the TAG did a couple of years ago was part of the motivation for adding the PlainYearMonth and PlainMonthDay types.

I do want to acknowledge that this is a matter of taste. While we've gotten some feedback that many developers seem to understand and agree with the idea of representing your data more precisely with strong types, certainly plenty of developers would be happier with a single, more generic class as you suggested. If they wanted to, these developers could use Temporal.ZonedDateTime as an "everything" class, but in the documentation and cookbook we don't currently encourage it to be used that way, since it could lead to the type of bugs mentioned above.

In any case, the decision to have multiple classes is foundational to the proposal and I don't believe it would be possible to change it at this point, unless we started over with a different proposal altogether. But I hope that this response helps mitigate the concerns you mentioned, certainly legitimate ones, about cognitive overhead.

Hopefully there will be some libraries that make this API easier to use for average users.

I'm hopeful that using Temporal.ZonedDateTime for everything would be at least as good of a solution as relying on a wrapper library. That said, if someone does make some sort of a "simplified Temporal" library, I wouldn't be overly sad, as Temporal gives better tools for doing this than the Date object ever did, and avoids the need for that wrapper library to contain a copy of the time zone database which users need to download over and over again.

it also forces the API to promote factory methods for object creation which need to be learned separately, as opposed to constructors.

I'm not certain of the link that you mentioned between multiple classes and factory methods; that is also a design decision that's a matter of taste, but I do think it's a separate one from the decision to have multiple classes. Speaking personally, I also prefer constructors above factory methods, but it's my understanding that that's not a universal opinion, and I think the current split between low-level constructors related directly to the data model, and high-level factory methods accepting more kinds of input, is a good compromise. We did have an earlier thread with Lea about this.

While reviewing, we also spotted a typo in your documentation: in the example here the unit is probably "seconds", not "minutes".

I think this has been fixed in the meantime, thanks!

@cynthia cynthia added Progress: review complete and removed Progress: propose closing we think it should be closed but are waiting on some feedback or consensus labels Mar 23, 2021
domenic pushed a commit to littledan/html that referenced this issue Aug 11, 2021
This patch lets Temporal objects be serialized, both in storage and with
postMessage, if they use built-in calendars and timezones. This is the
only expected integration of Temporal with HTML/DOM expected initially;
see earlier discussion in w3ctag/design-reviews#311

The current draft just includes Temporal.PlainDate, and it will be extended
to all of the Temporal types after initial review. This patch should not be
landed until (at least) Temporal reaches Stage 3.
domenic pushed a commit to littledan/html that referenced this issue Aug 11, 2021
This patch lets Temporal objects be serialized, both in storage and with
postMessage, if they use built-in calendars and timezones. This is the
only expected integration of Temporal with HTML/DOM expected initially;
see earlier discussion in w3ctag/design-reviews#311

The current draft just includes Temporal.PlainDate, and it will be extended
to all of the Temporal types after initial review. This patch should not be
landed until (at least) Temporal reaches Stage 3.
Ms2ger added a commit to littledan/html that referenced this issue Jun 20, 2024
This patch lets Temporal objects be serialized, both in storage and with
postMessage, if they use built-in calendars and timezones. This is the
only expected integration of Temporal with HTML/DOM expected initially;
see earlier discussion in w3ctag/design-reviews#311

Co-authored-by: Domenic Denicola <[email protected]>
Co-authored-by: Ms2ger <[email protected]>
Ms2ger added a commit to littledan/html that referenced this issue Jun 20, 2024
This patch lets Temporal objects be serialized, both in storage and with
postMessage, if they use built-in calendars and timezones. This is the
only expected integration of Temporal with HTML/DOM expected initially;
see earlier discussion in w3ctag/design-reviews#311

Co-authored-by: Domenic Denicola <[email protected]>
Co-authored-by: Ms2ger <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Progress: review complete Review type: later review Topic: scripting ECMA, Web Assembly bindings, etc. Topic: universal JavaScript Features that work on the web and non-web (e.g. node.js) Venue: TC39
Projects
None yet
Development

No branches or pull requests