Proposal-temporal: What should be the long-term name of `LocalDateTime` ?

Created on 26 Jun 2020  Ā·  147Comments  Ā·  Source: tc39/proposal-temporal

In #700, @InExtremaRes asked:

@justingrant Hi. I'm curious, why do you pick LocalDateTime as a name? If ZonedDateTime haven't been "occupied", were you choose that instead? I know you said is just a placeholder name, but I'd like to know your rationale behind that as, you know, names communicates a lot the intentions of a model.

I figure this won't be the last question/suggestion about the name of this type, so opening up this issue to coalesce feedback about naming. The current name is just a placeholder.

bikeshed documentation polyfill spec-text zoned-type

Most helpful comment

Copying from #700:

@InExtremaRes - Great question. I avoided Zoned* names because of the historical baggage, because this type (like @pipobscure noted) wasn't a close match to those earlier proposals, and finally because a goal of this type is to be friendly and enticing for new users who may not know which Temporal type is the right one for their use case. "Zoned" is not particularly friendly, and it's not even a real English word so isn't obvious for new users. "Local" is a familiar word that has the connotation of "in a particular place" which is closer to what I was hoping to achieve with a name. But really I just wanted a non-confusing placeholder until we had time to pick a final name.

That said, a concern I have with LocalDateTime as a long-term name is that Java uses the same name for its equivalent of Temporal's DateTime. So developers coming from Java might get confused.

When it comes time to pick the final name, I think it'd be helpful to consider both this type and the DateTime type's names together. IMHO, a goal of naming both these types should be to encourage new users who don't know Temporal to use LocalDateTime instead of DateTime, because the former type is safe for DST and the latter is not. So ideally, LocalDateTime would have a short and friendly name and DateTime would have a longer and/or less-friendly name.

Ironically, I have a stronger opinion about the name of DateTime, which I'd like to see as "ZonelessDateTime" or "PlainDateTime" or something like that that would make noobs think twice before using it.

For LocalDateTime, I don't have a great idea yet for what should be the final name. Feedback appreciated!

All 147 comments

Copying from #700:

@InExtremaRes - Great question. I avoided Zoned* names because of the historical baggage, because this type (like @pipobscure noted) wasn't a close match to those earlier proposals, and finally because a goal of this type is to be friendly and enticing for new users who may not know which Temporal type is the right one for their use case. "Zoned" is not particularly friendly, and it's not even a real English word so isn't obvious for new users. "Local" is a familiar word that has the connotation of "in a particular place" which is closer to what I was hoping to achieve with a name. But really I just wanted a non-confusing placeholder until we had time to pick a final name.

That said, a concern I have with LocalDateTime as a long-term name is that Java uses the same name for its equivalent of Temporal's DateTime. So developers coming from Java might get confused.

When it comes time to pick the final name, I think it'd be helpful to consider both this type and the DateTime type's names together. IMHO, a goal of naming both these types should be to encourage new users who don't know Temporal to use LocalDateTime instead of DateTime, because the former type is safe for DST and the latter is not. So ideally, LocalDateTime would have a short and friendly name and DateTime would have a longer and/or less-friendly name.

Ironically, I have a stronger opinion about the name of DateTime, which I'd like to see as "ZonelessDateTime" or "PlainDateTime" or something like that that would make noobs think twice before using it.

For LocalDateTime, I don't have a great idea yet for what should be the final name. Feedback appreciated!

I've followed this proposal from the start, but had to focus on other things for the past couple of months. I'm finally catching back up and was _very_ surprised to see the LocalDateTime name had come back. I'm especially surprised that it's come back in a form that's the opposite of how it was previously used (as LocalDateTime was one of the alternative naming options for CivilDateTime, which was later renamed to just DateTime once it was put under the Temporal namespace). As you pointed out, it's also in conflict to how the name LocalDateTime is used in Java.

Naming is important, and definitely hard, as all the previous bikeshedding issues and PRs about names have shown. The prior discussions most relevant to this particular issue are:

A particularly noteworthy comment is at https://github.com/tc39/proposal-temporal/issues/11#issuecomment-300198630:

It is also important to note that the alternative names are all negative BTW - "zoneless", "raw", "plain", "naive", "just", "only". Naming a class after what it is not is IMO a Bad Idea.

Personally, I don't see what's wrong with the name ZonedDateTime; it's a DateTime that is tied to a specific Zone. I have to disagree with your assertion in #700:

"Zoned" is not particularly friendly, and it's not even a real English word so isn't obvious for new users.

There are several points to make about this:

  1. The entire concept of handling dates and times correctly, accounting for all possible footguns, isn't obvious for new users. This was best put by @jskeet in https://github.com/tc39/proposal-temporal/issues/11#issuecomment-301592330:

In terms of the argument about it making it blindingly obvious: I believe the idea that anyone will come to a date/time library and be able to make the right decisions without reading any documentation is simply unrealistic. Whatever it's named, users will have to read docs. If there's a name which isn't hugely obvious before you've read the docs, but is fine when you _have_ read the docs, that seems reasonable to me

  1. Leaving aside semantics of the phrase "not a real word", "zoned" is categorically a defined English word. It's the past tense of the verb "zone", and is quite appropriate for this use case. Ref 1, Ref 2.

As a side note... I always liked the concept of a zoned date-time object (the previous ZonedDateTime and your current LocalDateTime). I never fully agreed with the reasoning/justification for dropping the old ZonedDateTime, because major API decisions were being made without any practical examples of how they affected common use cases. Now that we have the cookbook examples, better decisions can be made. Thank you for putting in the effort to make this concept work. :grin:

@gilmoreorless welcome back. I fully agree with you. I think the name is definitely a placeholder only šŸ˜„

Yep, the current name is just a placeholder. My suggestion is to defer the naming question for a few weeks while we define exactly how this new type will behave and how it will relate to other Temporal types. Also IMHO it will be helpful for folks to have a little time to play around with LocalDateTime sample code to get a real-world sense of how the type will be used.

Depending on the above, some names may be more or less appropriate. Also, I suspect that it will be a lot easier to get consensus on naming once we have consensus on scope/behavior/etc.

This is a nice way of suggesting that we don't cover the type-naming question in tomorrow's marathon meeting. ;-)

I'm fine with LocalDateTime → DateTime and DateTime → something else (PlainDateTime, AbstractDateTime, CalendarDateTime)
Another choice could be "Event" in line with the description of it as an event that happened at a particular time in a particular place.

I'm fine with LocalDateTime → DateTime and DateTime → something else (PlainDateTime, AbstractDateTime, CalendarDateTime)

Agreed. I'd add ZonelessDateTime to the "something else" list, with the goal of helping users understand that it's the type to use when you want the date and time but don't don't know (or don't care about) the time zone. PlainDateTime is a more subtle version of the same idea; you only need something "plain" if the "full" (or spicy!) thing is not available or appropriate.

I'd avoid Calendar* because it'd imply that types without that prefix don't use calendars.

Another choice could be "Event" in line with the description of it as an event that happened at a particular time in a particular place.

I agree in principle, but "Event" is used in the web platform (e.g. DOM events) to mean "something that happened in an interrupt-driven fashion" without LocalDateTime's emphasis on "in a real place". So I'd be inclined to avoid "Event" in Temporal to avoid that potential confusion.

Beware IF we were to go and rename DateTime to ā€œsomething elseā€ we’d also have to rename Date and Time (and possibly MonthDay and YearMonth) for consistency.

Also LocalDateTime is so much more than just a Date and Time that I’m not convinced that’s the way to go.

How about the other extreme: AbsoluteZonedDateTime

And in literature we can refer to it by its nickname: AZDT šŸ˜€

Beware IF we were to go and rename DateTime to ā€œsomething elseā€ we’d also have to rename Date and Time (and possibly MonthDay and YearMonth) for consistency.

I disagree, I wouldn't see a problem with having e.g. DateTime, PlainDateTime, Date, and Time. My reasoning is that there's no possibility to have a 'spicy' (as Justin put it) Date and Time.

Also LocalDateTime is so much more than just a Date and Time that I’m not convinced that’s the way to go.

Fair enough, something else along the lines of Event would satisfy that concern, but :-1: to AZDT :smile:

Some ideas.

Option 1: Based on the Data Model

| Current Temporal Name | New Temporal Name |
|---|---|
| DateTime | DateAndTime |
| LocalDateTime | LocalTimestamp |
| Absolute | Timestamp |

These names accurately reflect the data model, which I think can help developers think about the relationship between these types more effectively. I expanded "DateTime" to "DateAndTime" to make it look less friendly.

Option 2: Java-style

| Current Temporal Name | New Temporal Name |
|---|---|
| DateTime | LocalDateTime |
| LocalDateTime | ZonedDateTime |
| Absolute | Instant |

These names are based on the equivalent types in java.time.

Option 3 : Based on function

| Current Temporal Name | New Temporal Name |
|---|---|
| DateTime | CivilDateTime |
| LocalDateTime | ~DateTime~ Event |
| Absolute | Timestamp |

These names are intended to reflect the use cases. ~DateTime~ Event is your go-to choice when you want to represent an instant specific to a place and calendar system. CivilDateTime is a weird version of DateTime without a time zone.

EDIT 2020-09-02: I changed "DateTime" to "Event" to more accurately reflect the mental model.

I'm seeing several folks above mention this pattern:
1) LocalDateTime => DateTime
2) DateTime => XxxDateTime, where Xxx could be "Zoneless", "Plain", "Civil", "Abstract", etc.

Seems like a good pattern for discoverability, IMHO. I support this pattern. I don't have a strong opinion about Xxx, but I tried to order them above in my (slightly) preferred order.

:-1: Zoneless, Civil, Theoretical, Nonlocal, Ideal, Wall
:neutral_face: Plain, Pure, Relative
:+1: Abstract, Calendar

edit: I've kind of come around to AbstractDateTime. I also still like CalendarDateTime because it's the most descriptive of the names, in my opinion, although I will definitely concede that it's confusing because it implies that the other types don't have calendars.

Consistency is key, so if we end up renaming DateTime with something else so as to make DateTime available for this, then that means the same schema applies to Date and Time.

So we’re back at prefixing the basic types (DateTime , Date & Time) just to benefit something that is more specialized and thereby suggesting its use for cases it unsuited for.

For those reasons I’m against prefixing the current objects and for contemplating suitable names for LocalDateTime only.

Given it’s decided semantics as some event on the absolute timeline in sone specific place I find LocalDateTime quite appropriate. Alternatively ZonedDateTime is a contender. Optimally we’d have a simple (i.e. non-compounded) name like Event (which is ruled out, but like it). Maybe TimeEvent or EventTime or Occurrance?

What I posted above as Option 1 is currently my favorite. https://github.com/tc39/proposal-temporal/issues/707#issuecomment-682177137

DateTime becomes DateAndTime, for reasons I've discussed previously: DateTime is an overloaded term in programming, so in my opinion, it is a good idea not to use that term at all. We can use DateAndTime to emphasize the nature of this type.

LocalDateTime becomes LocalTimestamp (or LocalAbsolute), accurately reflecting its data model. I like the prefixed "Local" instead of "Zoned" because the type also carries a calendar, not just a time zone, relative to the regular Timestamp/Absolute. "Local" reflects that this is a localized timestamp in multiple ways.

It will be very awkward to have a conjunction in the name; ā€œDateAndTimeā€ seems like a poor choice.

First choice: A name like Event. EventTime and Occurrence are not quite it, but maybe we can come up with one? Could we actually reuse Instant for this, or even Moment (with apologies to moment.js)? (Thesaurus suggests some others that I don't like: Incident? Happening? Circumstance? Occasion?)

Second choice: LocalDateTime → DateTime, DateTime → AbstractDateTime. (I disagree that this would make it necessary to rename Date and Time as well. It's not possible to have a zoned Date or a zoned Time, so there's no ambiguity.)

Last choice: use the Java names but keep Timestamp instead of Instant.

I think "Local" and "Civil" had already been rejected years ago for good reasons, and especially Local could be argued to be a good name for (the types that are currently called) LocalDateTime or DateTime.

Second choice: LocalDateTime → DateTime, DateTime → AbstractDateTime. (I disagree that this would make it necessary to rename Date and Time as well. It's not possible to have a zoned Date or a zoned Time, so there's no ambiguity.)

It’s not about ambiguity, it’s about consistency. It makes AbstractDateTime seem different from Date and Time where it is very similar and it make (Local)DateTime seem similar to Date and Time where it is very different. It also puts (Local)DateTime into a spot of pre-eminence it’s not properly in.

For all these reasons (and a few I haven’t thought of yet) this is option 100 in my order of preference right after naming all out classes Temporal.0 through Temporal.9

I think "Local" and "Civil" had already been rejected years ago for good reasons, and especially Local could be argued to be a good name for (the types that are currently called) LocalDateTime or DateTime.

Local was dismissed for the classes that currently live without a prefix. For the current LocalDateTime it’s actually appropriate. Civil was only dismissed because it became unnecessary to prefix given a Temporal global object, so I’d say it’s definitely in the game.

As a matter of fact I’d like to suggest not changing the name of LocalDateTime at all, or if so then changing the DateTime part rather than the Local part. So how about LocalEvent?

I think it'd be helpful to be explicit about the prioritization framework we're using to guide our preferences. Here's mine, in ranked order:

  1. Ecosystem Reliability, which IMHO here means preventing users from assuming that the type currently named DateTime will adjust for DST. Since I first joined this project this has been my top reliability concern with Temporal. Even experts can make this mistake, e.g. https://github.com/tc39/proposal-temporal/pull/860#issuecomment-683186998. FWIW, concern about the DST bugs this mistake would cause is the main reason I've spent the last few months helping to flesh out the LocalDateTime proposal!
  2. Discoverability / Learnability. Make it obvious to new users what use cases each type should be used for, ideally by picking words that already have meaning for desired use cases of each type and (just as important) _don't_ have meaning for use cases we want users to avoid for each type. In other words: maximize recognition while minimizing ambiguity.
  3. Ergonomics, which for type names really means short and easy to spell
  4. Consistency which I see primarily as a means to an end to achieve the priorities above. It's possible to make things more consistent but harder to use, so ideally we'd avoid that kind of consistency. ;-)

With these priorities in mind, my current preference is:

  • DateTime => CivilDateTime OR DateTime => ZonelessDateTime (prefer the latter, but both are OK)
  • LocalDateTime => DateTime
  • Leave Date, Time, MonthDay, YearMonth as-is

Why?

  • "Civil" is the clearest possible term for experts. It's what Wikipedia calls this concept!
  • "Civil" is a completely unknown term for non-experts, so will discourage accidental use of any type with this prefix.
  • I also like ZonelessDateTime because it also solves the problem of preventing accidental use (esp. by non-experts) while being super-obvious what use cases it should be used for. I actually prefer this more than CivilDateTime because it will be more discoverable for non-experts who occasionally have the need for a zoneless type, but it's also unpopular among the Champions. So I'm happy to follow the wisdom of the crowd between these two names because my top concern (accidental use causing DST bugs) will be addressed either way.
  • Date, Time, etc. have no corresponding DST-unsafe type that we need to scare novices away from, so IMHO adding a prefix (especially a prefix that's explicitly designed to discourage use!) would unnecessarily impede higher-priority Discoverability and Ergonomics goals for those types.

But honestly I care more about the priorities than specific names. I'd be happy with other names that fulfill the same goals.

@justingrant Do you feel that my proposed LocalDateTime => LocalTimestamp and DateTime => DateAndTime (or perhaps CivilDateTime in light of @ljharb's comment) satisfies your priorities?

  1. Ecosystem Reliability: We eliminate a type named DateTime.
  2. Discoverability / Learnability: Most users should arrive at LocalTimestamp, because Timestamp doesn't have datetime fields and CivilDateTime or DateAndTime sounds scary. The type names are self-explanatory of their data model.
  3. Ergonomics: I think LocalTimestamp is easy enough to spell.
  4. Consistency: Not sure what you mean by this, but the type names are consistent with their data model.

I can also see some merits about naming the types based on the mental model / intended use case (e.g. Event).

Why I'm not super fond of LocalDateTime => DateTime:

  1. "DateTime" is an overloaded term in this industry that is likely to bring problematic preconceptions about what the type is supposed to do.
  2. The name "DateTime" corresponds to neither the data model (timestamp+timezone+calendar) nor the mental model (an event that occurred at a place).

@justingrant Do you feel that my proposed LocalDateTime => LocalTimestamp and DateTime => DateAndTime (or perhaps CivilDateTime in light of @ljharb's comment) satisfies your priorities?

Nope. I think LocalTimestamp is actually worse than neutral because "Timestamp" implies (and will be documented as) "a machine-readable thing that doesn't have a date or a time". Attaching an ambiguous word like "Local" (does it mean "my time zone"? "anyone's time zone?" "no time zone?") to it won't undo the core problem that the word "Timestamp" would actively impede users from thinking that it'd work for their Date/Time use cases. FWIW, I picked the name "LocalDateTime" as a placeholder name specifically because it was so ambiguous so no one would think it was meant to be the final name. ;-)

The fact that LocalDateTime is implemented using a timestamp is really just an implementation detail. From the user's perspective, a LocalDateTime is a date, a time, an offset, and a time zone. Using at least some of those words in the name will help discoverability. And if the zoneless type has "Date" and "Time" in the name and the zoned type does not, it's perhaps the worst possible discoverability outcome.

"DateTime" is an overloaded term in this industry that is likely to bring problematic preconceptions about what the type is supposed to do.

I'm not sure this is a bad thing. Discoverability workflows have 1-2 steps:

  • "initial discoverability" - this is mainly whether the name of something corresponds to the name of some other familiar thing, either in plain English or in another programming context. Ideally, there's one obvious initial choice for most/all popular use cases.
  • "subsequent discoverability" - if the initial thing isn't right for your use case, does your first pick help you get closer to the next one, and so on until you find the best one for your use case? Or does it take you to a dead end where you need to back up and start over? This is why I like DateTime for the zoned type and XxxDateTime for the zoneless type, because in the less-common case where you really want a zoneless type, your first pick will help you find it.

Here's another way to think about the discoverability process:

  • The best outcome is when your initial choice is right.
  • The second-best outcome is when your initial choice makes it easy for you to discover the right choice in an obvious way. For example, if you try to parse a bracketless string into a zone-required type called DateTime and you get an exception complaining that the time zone is missing, this is a pretty good signal about how the type works and about what your likely next steps could be (e.g. add a time zone, find a zoneless type, etc.)
  • The third-best outcome is when there's no obvious initial choice and you must read the docs for all types to find the right one.
  • The worst outcome is when your initial choice seems like the right one so you stop looking for the right one. This outcome doesn't just make discoverability harder. It also breaks software. strcpy vs strncpy in C is a good example. I'd argue that string.prototype.toUpperCase vs. string.prototype.toLocaleUpperCase is another. So is, IMHO, DateTime and ZonedDateTime.

Anyway, I see DateTime for a zoned type as either the first or second outcome in the list above. Either the user knows the time zone and will be happy, or they don't and they'll be quickly guided (by exceptions, error messages, IDE parameter help, etc.) to look for the correct type for their use case.

FWIW, Joda Time (which was the basis of Java.time) used DateTime for the name of the zoned type before the Java folks renamed it to ZonedDateTime. So there's at least some precedent for DateTime to mean a zoned type.

BTW, although I prefer DateTime for the zoned type and either ZonelessDateTime or CivilDateTime (or any other XxxDatteTime) for the zoneless one, a distant second choice that I like better than all the others proposed so far would be ZonedDateTime and ZonelessDateTime. I don't like how this pair is less opinionated about which type to try first; I suspect this would make it less good at the #1 "reliability" item in my priority list. And it's less ergonomic (#3). But Zoned/Zoneless is very discoverable (#2) and very consistent (#4).

Attaching an ambiguous word like "Local" (does it mean "my time zone"? "anyone's time zone?" "no time zone?") to it won't undo the core problem that the word "Timestamp" would actively impede users from thinking that it'd work for their Date/Time use cases.

But I belive the charter of LocalDateTime is to represent an event (timestamp) that occurred at a particular location (time zone and calendar system). The fact that it works nicely with date/time timezone math is a convenient afterthought.

The fact that LocalDateTime is implemented using a timestamp is really just an implementation detail. From the user's perspective, a LocalDateTime is a date, a time, an offset, and a time zone.

I disagree with that premise. Unlike what's currently called DateTime, a LocalDateTime represents an unambiguous instant in time; it just has a location (time zone and calendar system) attached to it. It's a fallacy to think of it as a date, time, offset, and time zone, because not every combination of those elements can be represented by a LocalDateTime (say 2:30am the night of a spring forward DST transition).

But I believe the charter of LocalDateTime is to represent an event (timestamp) that occurred at a particular location (time zone and calendar system). The fact that it works nicely with date/time timezone math is a convenient afterthought.

I actually wasn't thinking of math here. I was more thinking about Date and Time fields. Many developers wouldn't expect a type named "XxxTimestamp" to have those fields.

But I also think it's fine to think of it as an Absolute+TimeZone. Both viewpoints are correct, which I actually think is an advantage of LDT because I expect both viewpoints will be present among users of Temporal. Some developers will naturally gravitate to one view or the other, and I think that's OK.

BTW, this reminds me of an insight I heard from an old colleague that I think applies here:

  • Experienced, systems-level developers tend to approach programming like physicists: from the inside out. They start with the conceptual framework and how things work under the hood. For these folks, "What is it?" is the most important question.
  • On the other hand, junior developers tend to approach new APIs like a child with a new toy. They look at the outside to see what knobs and switches there are, and then they start pushing buttons to see what happens. "What does it do?" is the important question for them. Only later after using it for a while do they fully understand the underlying concepts.

Anyway, my point in the comment above was that from the junior-developer POV of looking at the outside of the type, LDT feels more like today's DateTime and less like today's Absolute. For these developers, the word "Timestamp" would make it harder to discover this type.

It's a fallacy to think of it as a date, time, offset, and time zone, because not every combination of those elements can be represented by a LocalDateTime (say 2:30am the night of a spring forward DST transition).

I don't think I agree with this statement. Aggregates can place restrictions on their content without invalidating the essence of the combination. A userland Fraction type composed of two Number fields isn't a fallacy if its author decides that its constructor should throw if the divisor is zero.

The "What is it?" versus "What does it do?" insight is very relevant here.

I actually wasn't thinking of math here. I was more thinking about Date and Time fields. Many developers wouldn't expect a type named "XxxTimestamp" to have those fields.

I want programmers to think about date getters as being tied to the calendar system. Types that carry a calendar are equivalent to those that have date getters and support date math.

"LocalTimestamp" is descriptive, because "local" suggests both a time zone and a calendar system. When I was chatting with Ujjwal the other day, I suggested that we could name the Absolute -> LDT transition function "localize", taking the two arguments (time zone and calendar), to emphasize what "local" means.

For comparison, I wouldn't like "ZonedTimestamp", because it suggests a Timestamp+TimeZone data model; however, we made the very significant decision to also include a Calendar in the LDT data model. Similarly, "CalendaredTimestamp" is misleading because it does not indicate the presence of a time zone.

While I’m Ok with Timestamp for what is currently called Absolute I strongly oppose it for this.

LocalDateTime is NOT a Timestamp attached to a Timezone in any but meaning but the datamodel we happen to choose for the polyfill.

I also don’t care about what the current experts in the field think too much. And here is why:

Experts in any field retire and get old and new ones grow. As such ā€œwhat is expected and knownā€ is actually not that important because it changes over time. For example when I was young literally literally meant literally but these say the meaning has changed to figuratively and we no longer have a word meaning literally.

Much more important is the mental mode we establish and that this is internally consistent. If we do that, then the coming generations of experts in the field have a much easier time to emerge.

Our mental model is that:

  • Absolute is an absolute fixed moment in time
  • Date is a wall-calendar (like the one hung in my kitchen)
  • Time is a wall-clock
  • DateTime is a wall-clock hung next to a calendar
  • LocalDateTime is a date and time carefully adjusted to a timezone so as to match it.

Just because there is a randomness factor introduced called DST that makes that date & time & timezone tuple not entirely unambiguous therefore forcing us to use an absolute in the polyfill does not change that mental model.

So while at the start LocalDateTime was named thinking that’ll not be its name, that very name has helped shape the thing as well. So I’d still urge us to consider it.

So as a matter of fact the statement:

But I belive the charter of LocalDateTime is to represent an event (timestamp) that occurred at a particular location (time zone and calendar system). The fact that it works nicely with date/time timezone math is a convenient afterthought.

is entirely misguided in my view. On the contrary:

the charter of LocalDateTime is to attach a date and time to a timezone. The fact that moves it so close to representing a timestamp (only requiring a bit of disambiguation) and the fact that unambiguous values are important anyhow make using an Absolute in the datamodel an after thought for the polyfill.

Just a note: https://github.com/tc39/proposal-temporal/issues/1#issuecomment-313887441, from back in 2017, had suggested ZonedInstant and PlainDateTime. :thinking:

I just read https://github.com/tc39/proposal-temporal/issues/887#issuecomment-691589636 which is a fascinating account of a new Temporal user trying to understand the API. It has a lot of relevant content re: naming, so I'm pasting it below.

I believe my main misunderstanding is Absolute vs DateTime. Although I read the documentation, I was under the impression that the former represented an absolute time meaning without reference to a timezone, which can be interpreted as defaulted to the, well default timezone (UTC). However reading the docs now in light of this conversation makes me realize I don't get their difference and specifically what an Absolute is meant to represent.

I think this is the model I have in mind, surely biased by the model I have been using in JS or PHP. I won't discuss the calendar part because I'm totally unfamiliar with that concept/tool (curious to learn more about it though).

temporal-graph-model

Temporal

In my mind the DateTime class, the higher in the hierarchy here, should describe _ANY_ "moment in time" that Temporal aims to represent, which needs to include a date, a time and a timezone. Now, with this interpretation, an Absolute instance is basically a DateTime without TimeZone, which can be simply interpreted as a UTC (or Unix) instance (i.e. a DateTime with UTC timezone). In fact, absolute can be interpreted as in "no reference" to timezone, but also as "referenced to the universal/absolute" timezone: the result/behaviour I believe is the same for all intents and purposes.

As you can see, in this model a DateTime is "composed" or "identified" by an Absolute and a TimeZone, while an Absolute is identified by a Date and Time. DayMonth and MonthYear are instead different parts of a Date.
All this I believe well matches the string ISO representation of the timestamp, which by itself (or portion(s) of it) is a very good reference to use (šŸ‘ ) for describing the classes and how to "switch" between them.

In this scenario an additional LocalDateTime class is unnecessary (although looking at #700 and #884 (comment) what is now called LocalDateTime more closely represents the DateTime in my model). Also, the term "local" in the name to me would mean local to the system. So for example I'd assume the default timezone of a LocalDateTime (if a timezone is not passed to the constructor) would be the system timezone, whereas UTC would be the default to a DateTime (although that would be an Absolute).

As a side note, I believe the model I presented closely matches the underlying model of extremely popular and reliable libraries like Moment.js/Day.js and PHP Carbon, which I used for many years.

I find @sffc’s first option intuitive and clear (DateAndTime, LocalTimestamp, Timestamp). The particular terms don’t matter much (could as easily be DateTime, LocalizedInstant, Instant), but it seems like the latter two describe specific instants in time while the first doesn’t and that this would be the most important thing to convey up-front.

Maybe I’m misunderstanding something though. Is there really something that makes a date-and-time-and-time-zone value less ā€œabsoluteā€ than the thing being called ā€œabsoluteā€? Isn’t it an absolute time with additional metadata to provide a lens for formatting, etc?

My mind model on this is, is that timezone is actually a spatial/geographical value. It sets a location (or location constraint) on the globe for a given instant in time. For this reason, I've always found java's LocalDateTime confusing. To me it's ambiguous. I agree the "default" name should be the one with timezone information as any date and time values have this (at least implicitly).

The concept of time without a timezone would be a metric from the perspective of:
1- An entity outside the earth
2- An entity at all place at the same time
3- An Entity localized on an unknown location

Conclusion:
DateTime for values with timezone info.
For values without timezone info something like (more advanced names):
1 - UniverseDateTime or AlienDateTime
2 - OmniDateTime - as in Ominipresent
3- UnknownLocationDateTime or UndistinguishedDateTime

I severely disagree with this. To explain I will tell a little story:

There once was a pilot called Robin. He was flying around one day when he got into a storm that carried him off course and eventually caused him to crash on an island. Luckily Robin wasn't injured, but he was unconscious for an indeterminate amount of time.

When Robin awoke, he had no idea where he was or how long he was out. So Robin wound up his watch and set it by the Zenith of the sun and set his calendar to something more or less random and began to establish himself on the island. Every day he would write in his diary describing his day. He would list everything he was done with a date and time he took from his watch and his calendar.

Many years later he was getting old and knew he was going to die soon. So he put all his diaries into a waterproof box on a float and set it out to sea hoping that someone would find it and that he would be remembered.

And his box was actually found which is why we know about Robin. Of course we still don't know exactly when and where this actually happened, we never found the island; and even if we did, we'd not know exactly when this all happened.

What we do know is that Robin would have been using, if he had had a computer with Temporal, is the default type DateTime. And it is in effect what we all use by default. Until we learn about timezones we just look at our watches and calendars and trust that they're set to something sensible.

Only "advanced users" (i.e. adults who have learned about dst & zones) ever bother with timezones and translating between them.


And this is why the basic types are called Date, Time and DateTime. Anything else needs to be marked to indicate what extras it brings to the table.

Now what does LocalDateTime bring to the table? It brings a TimeZone with it that allows it to attach to the posix timeline and follow the DST rules for the zone.

There are 2 important take-aways from this:

  1. This is definitely NOT the default DateTime and should definitely NOT be called that or anything indicating that.
  2. This is (in terms of concept) NOT an Instant with a TimeZone but rather a DateTime with a TimeZone. (even though for practicality we also retain the Instant)

I agree with the idea of having a "main" class DateTime handling date, time _and_ timezone (i.e. replacing/renaming the current LocalDateTime class). I think it's reasonable to assume that any developer approaching Temporal would expect the basic class to handle DST and such.

Now, what about UtcDateTime or UnixDateTime in place of the current DateTime?

After all a DateTime (as in a timestamp without a timezone) is in fact equivalent to (if not the same exact thing) a UTC LocalDateTime, under every aspects. I have not seen this association, which comes automatic to me, anywhere in this repo and I wonder why.
UTC and Unix are popular and well known concepts which would probably convey the "no timezone" or "no DST" idea quite intuitively to expert and non expert developers. I also wonder why they are not used much in this proposal.

And that’s precisely WHY I strongly object to this change. Basically everything you said in your second and third paragraph is entirely wrong and very misleading! And the fact that you wrote it means that this needs MORE emphasis not less.

@pipobscure would you please elaborate on why do you think my assumption is wrong? I honestly don't see why, but I might miss some detail

First DateTime is not ā€œa timestamp without a timezoneā€. This is just wrong on a lot of levels.

DateTime is what you get when you take a wallclock without a battery and nail it up next to a wall-calendar. It has no direct relationship to any timeline in any way. It’s only a representation of a date and a time. It’s not even necessarily related to the date/time locally. (Imagine an old watch and calendar in an attic storage)

So relating it to UTC is just really wrong. Your reasoning is a classic example of ā€œpost hoc ergo propter hocā€ in falaciously assuming that because a DateTime acts very much like a LocalDateTime with UTC as timezone it is actually that.

The second item that’s incorrect is that UTC conveys ā€œno dstā€ or ā€œno timezoneā€. It’s just a normal timezone that represents the mean solar time at 0 degrees. So conflating this with DateTime is just very wrong.

Lastly there os no ā€œmainā€ class in Temporal. There is also no ā€œentry pointā€. There are simply a set of classes that represent distinct concepts.

Now I agree that LocalDateTime is not necessarily the best name. But renaming it to DateTime and breaking all meaningful naming and cohesion of all classes is simply not a good idea.

DateTime is what you get when you take a wallclock without a battery and nail it up next to a wall-calendar.

can we get rid of DateTIme then?
why do we even need wall-clocks and wall-calendars in javascript? i can't think of any scenario in javascript where this "concept" is useful.

when i'm setting/getting isostrings from ui-elements or databases, its always going to be in a locale/utc context.

Here's a few use cases where it can be helpful to have a timezone-less date and time type:

  1. Interop with platforms that have the comparable type. For example, SQL Server's DATETIME type has no concept of time zone. Other DBMSs have similar types.
  2. Interacting with other computing components (e.g. UI date/time pickers) that are not timezone-aware. The use case above is really just a special case of this more general one. Many other parts of the computing ecosystem don't deal with local-specific date/time data, and Temporal needs to support interacting with those parts.
  3. Supporting cases where time zone and date/time are stored or used separately. Partly because other platforms' limitations noted above, it's common for apps to store date/time and timezone separately. For example the JSCalendar spec (iCalender for JSON) does this. So when you're writing a JSCalendar object, you'd need to decompose a LocalDateTime into a zoneless date/time and a timezone, and you'd do the reverse when reading one.
  4. Representing events that happen at the same time in every time zone. For a silly example, there's a "cannabis holiday" every year on April 20 (4/20 in the US) and there are events that day at 4:20PM regardless of time zone. Modeling that event in Temporal would be 2020-04-20T16:20 with no time zone reference.
  5. Comparing Date/Time in Different Time Zones Relative to Local Time. For example: was yesterday's sunset in Olso earlier or later (in local time) than the sunset in Reykyavik?

I agree with you that these use cases may not be as common as other Temporal types like Absolute (soon to be renamed Instant), Date, Time, and LocalDateTime (also soon to be renamed). But IMHO the use cases above are valuable enough and common enough to justify the type.

The second item that’s incorrect is that UTC conveys ā€œno dstā€ or ā€œno timezoneā€. It’s just a normal timezone that represents the mean solar time at 0 degrees. So conflating this with DateTime is just very wrong.

@pipobscure I believe this is incorrect. By definition UTC has no timezone, in fact it is the reference (thus the universal part) date+time which the timezone/offset is applied to. Since it does not have a timezone it does not carry DST information (again by definition).
Now, a (Local)DateTime with Europe/London (timezone) or +00:00 (offset) defines a time that coincides with UTC (only for part of the year in the former case) and I agree it is not the same as a UTC instance, because for example they both provide DST information.

However, to me you are describing DateTime as an absolute/unchangeable (not to say immutable that has typically another meaning here) point in time. But to me, for what I understand from the docs, that is what Absolute is for.

The term "absolute" BTW implies that there is also a "relative". To me, in this context, this automatically translate to
Absolute = "UTC" and LocalDateTime = "with timezone" i.e. "relative to UTC".
Does that sound obvious/natural only to me?

You are right: UTC does not HAVE a timezone, it IS a timezone.

Absolute (or Instant as we’ve finalised on) is NOT a Date/Time thing at all. It is a point on the posix timeline, but has no idea of anything date or time related. For example it lacks a calendar which means there are no years or months or days or ...

So it is the very opposite of an Instant.

Your last bit has a point:

  • Instant - an absolute instant on the timeline
  • LocalDateTime - a date/time relative to a timezone
  • DateTime - a date/time so relative that it only relates to other DateTime values

So it is the very opposite of an Instant.

@pipobscure you mean opposite of a DateTime, right?

So it is the very opposite of an Instant.

@pipobscure you mean opposite of a DateTime, right?

I meant that DateTime is the opposite of an Instant. To convert between them you use a TimeZone and if you want to maintain the state of that transition you have a LocalDateTime

@stebogit we need wall clocks and wall calendars in JS for the same reason we need them in real life.

A couple of things from previous comments we must be careful:

The second item that’s incorrect is that UTC conveys ā€œno dstā€ or ā€œno timezoneā€. It’s just a normal timezone that represents the mean solar time at 0 degrees. So conflating this with DateTime is just very wrong.

@pipobscure I believe this is incorrect. By definition UTC has no timezone, in fact it is the reference (thus the universal part) date+time which the timezone/offset is applied to. Since it does not have a timezone it does not carry DST information (again by definition).
Now, a (Local)DateTime with Europe/London (timezone) or +00:00 (offset) defines a time that coincides with UTC (only for part of the year in the former case) and I agree it is not the same as a UTC instance, because for example they both provide DST information.

Timezone and DST are completely unrelated concepts. I live in Brasil (we have 4 different timezones). Up until last year, some places had 1 hour DST. Last year the government decided to abolish DST completely. This definition changed several times over the last 2 decades. To me, DST is extremely arbitrary and a completely different topic of discussion.

After all a DateTime (as in a timestamp without a timezone) is in fact equivalent to (if not the same exact thing) a UTC LocalDateTime, under every aspects. I have not seen this association, which comes automatic to me, anywhere in this repo and I wonder why.

2- We may choose to use DateTime (or the "standard" name) to be the one with or without timezone. But if it's decided to have timezone info. I think it's best to default it to the current system timezone, if possible (default to UTC if not). To me is confusing the following (being on TZ GMT-3).

new Date('2020-08-24').getDate()
//> outputs: 23
new Date('2020-08-24T00:03:00').getDate()
//> outputs: 24

This happens precisely because parsing without timezone means to UTC and "getDate" output means system TZ. Defining both to be UTC, might resolve the specific behavior, but if this date is sent to a different system at any moment, TZ would probably not be one expected. Assuming UTC as default is not how we think about date and time. we assume current TZ as default.
This may be standard. I honestly don't know. But feels confusing to me, especially for newbies. To figure it should include TZ info, as such:

 new Date('2020-08-24T00:00:00.00-0300').getDate()
//> outputs: 24

Even when interchanging data (as in a REST service), I think it would be best to assume the sending part and the receiving part to be on the same timezone. right ?
I'm not sure if there are other cases where this behavior makes more sense, though.

I severely disagree with this. To explain I will tell a little story:

There once was a pilot called Robin. He was flying around one day when he got into a storm that carried him off course and eventually caused him to crash on an island. Luckily Robin wasn't injured, but he was unconscious for an indeterminate amount of time.

When Robin awoke, he had no idea where he was or how long he was out. So Robin wound up his watch and set it by the Zenith of the sun and set his calendar to something more or less random and began to establish himself on the island. Every day he would write in his diary describing his day. He would list everything he was done with a date and time he took from his watch and his calendar.

Many years later he was getting old and knew he was going to die soon. So he put all his diaries into a waterproof box on a float and set it out to sea hoping that someone would find it and that he would be remembered.

And his box was actually found which is why we know about Robin. Of course we still don't know exactly when and where this actually happened, we never found the island; and even if we did, we'd not know exactly when this all happened.

What we do know is that Robin would have been using, if he had had a computer with Temporal, is the default type DateTime. And it is in effect what we all use by default. Until we learn about timezones we just look at our watches and calendars and trust that they're set to something sensible.

Only "advanced users" (i.e. adults who have learned about dst & zones) ever bother with timezones and translating between them.

And this is why the basic types are called Date, Time and DateTime. Anything else needs to be marked to indicate what _extras_ it brings to the table.

Now what does LocalDateTime bring to the table? It brings a TimeZone with it that allows it to attach to the posix timeline and follow the DST rules for the zone.

There are 2 important take-aways from this:

  1. This is definitely NOT the default DateTime and should definitely NOT be called that or anything indicating that.
  2. This is (in terms of concept) NOT an Instant with a TimeZone but rather a DateTime with a TimeZone. (even though for practicality we also retain the Instant)

I severely disagree with this. To explain I will tell a little story:

There once was a pilot called Robin. He was flying around one day when he got into a storm that carried him off course and eventually caused him to crash on an island. Luckily Robin wasn't injured, but he was unconscious for an indeterminate amount of time.

When Robin awoke, he had no idea where he was or how long he was out. So Robin wound up his watch and set it by the Zenith of the sun and set his calendar to something more or less random and began to establish himself on the island. Every day he would write in his diary describing his day. He would list everything he was done with a date and time he took from his watch and his calendar.

Many years later he was getting old and knew he was going to die soon. So he put all his diaries into a waterproof box on a float and set it out to sea hoping that someone would find it and that he would be remembered.

And his box was actually found which is why we know about Robin. Of course we still don't know exactly when and where this actually happened, we never found the island; and even if we did, we'd not know exactly when this all happened.

What we do know is that Robin would have been using, if he had had a computer with Temporal, is the default type DateTime. And it is in effect what we all use by default. Until we learn about timezones we just look at our watches and calendars and trust that they're set to something sensible.

Only "advanced users" (i.e. adults who have learned about dst & zones) ever bother with timezones and translating between them.

And this is why the basic types are called Date, Time and DateTime. Anything else needs to be marked to indicate what _extras_ it brings to the table.

Now what does LocalDateTime bring to the table? It brings a TimeZone with it that allows it to attach to the posix timeline and follow the DST rules for the zone.

There are 2 important take-aways from this:

  1. This is definitely NOT the default DateTime and should definitely NOT be called that or anything indicating that.
  2. This is (in terms of concept) NOT an Instant with a TimeZone but rather a DateTime with a TimeZone. (even though for practicality we also retain the Instant)

I know basically nothing about Zeniths. But isn't suns Zenith used in navigation to estimate someone's location?

Anyway, when Robin sets his clock to any given day/time He is actually (implicitly) defining a TZ (approximately at least). Imagine he had an offline database of all moon eclipses in UTC. He wouldn't be able to compare both to know at which point he should be looking at the sky to try to watch the eclipse.

The point being. If DateTime is assumed to not have TZ info. You have a few options when comparing it to another date with TZ info. An assumption must be made about the perspective of the zoneless date, anyway.
If you decide to ignore TZ info of the compared date. You are actually just assuming the zoneless date to be on the TZ of the compared date. If you do it again with another date from another TZ. You are now assuming the zoneless date to be in another TZ. Thus, the perspective is omnipresent. It is at all places at the same time. (Cannabis Holiday or New Year countdown case)

By throwing an error. You are assuming the zoneless date to be in an unknown TZ. Thus, the perspective is from an undisclosed location (Robin's case). Or You are assuming zoneless date to be in a different system, which Would make it impossible to be compared to dates in our system. (If Robin woke up on a different earthly planet with one sun). Thus, an alien perspective.

Maybe we should have both ways, or should be able to use both strategies when comparing two dates (that maybe are zoned or zoneless). I don't know.

This discussion is actually convincing me to favour Temporal.DateTime → Temporal.NaiveDateTime, as someone suggested in the Twitter thread. "DateTime is a date and time without time zone info" is technically correct but suggests the wrong thing. It sounds like it's more accurate to say that DateTime is "naive" in that it doesn't even know that such things as time zones exist.

The point being. If DateTime is assumed to not have TZ info. You have a few options when comparing it to another date with TZ info. An assumption must be made about the perspective of the zoneless date, anyway.
If you decide to ignore TZ info of the compared date. You are actually just assuming the zoneless date to be on the TZ of the compared date. If you do it again with another date from another TZ. You are now assuming the zoneless date to be in another TZ.

This is quite true, and it's why we don't allow comparing objects of different types in Temporal. You must explicitly say what your assumption is, by converting one of the objects to the same type as the other. For example, if you want to ignore the time zone of the LocalDateTime and do a naive comparison, you do Temporal.DateTime.compare(ldt.toDateTime(), dt). If you want to assume the zoneless DateTime has the time zone of the LocalDateTime, you do Temporal.LocalDateTime.compare(ldt, dt.toLocalDateTime(ldt.timeZone)).

I’m OK with that iff that also means:

DateTime -> NaiveDateTime
Date -> NaiveDate
Time -> NaiveTime

and explicitly NOT

LocalDateTime -> DateTime

such that there is no type called DateTime afterwards.

-1 on "Naive", according to Google's style guide for inclusive language which discourages the use of ableist language. Although "naive" isn't explicitly listed as a red flag, it seems close to "dummy", which is.

I can see how it might be taken that way, so we should avoid it. It's a pity though, because I can't think of a one-word synonym for it that doesn't have the exactly wrong effect, e.g. "simple" would actually encourage reaching for it as a general rule, instead of discouraging using it unless you actually want its functionality. "Ignorant" is maybe a more inclusive synonym since it implies ignorance by choice, whereas someone might get called "naive" through no fault of their own. But IgnorantDateTime is just... no.

Would the maintainers of Google's style guide consider adding "naive" to the list of non-recommended words and coming up with recommended alternatives for getting the same point across? It will probably be too late for this discussion, but it might help others.

I actually can't see how naive is anywhere near dummy. It's not a synonym by any stretch of the imagination.

The dictionary https://www.google.co.uk/search?q=define:naive

defines it as

  1. showing a lack of experience, wisdom, or judgement.
  2. natural and unaffected; innocent
  3. of or denoting art produced in a style which deliberately rejects sophisticated artistic techniques and has a bold directness resembling a child's work, typically in bright colours with little or no perspective

nowhere does it indicate anything even close to ablist. @sffc please check with your folks if you want, but I truly think it's exactly the word we want.

If we were to accept the premise then many words including "natural" (see W Shakespeare) would have to be excluded leaving a language devoid of words.

That being said, I'm very happy with the fact that we examine our language and naming. Which is among the reasons Temporal has been using a "main" branch for a long time. So if there is any english language dictionary that puts naive with dummy or similar ablist term, I'm happy to concede the point.

I don't think a slippery slope argument is valid or helpful here. I don't think "naive" conveys the desired meaning anyways, and I do think it has an unfortunate connotation that should be avoided, and we do, absolutely, have to avoid words that would offend - TC39's code of conduct has already aggressively embraced this premise.

It's not just a date/time that's unaware of the concept of timezones - a DateTime is the same time in every timezone. Meaning, it stays the same no matter what the timezone is, intentionally. This isn't ignorance of timezones, it's intentionally standing apart from them.

I don't think a slippery slope argument is valid or helpful here. I don't think "naive" conveys the desired meaning anyways, and I do think it has an unfortunate connotation that should be avoided, and we do, absolutely, have to avoid words that would offend - TC39's code of conduct has already aggressively embraced this premise.

It's not just a date/time that's unaware of the concept of timezones - a DateTime is the same time in every timezone. Meaning, it stays the same no matter what the timezone is, intentionally. This isn't ignorance of timezones, it's intentionally standing apart from them.

Sorry if I wasn't clear, the premise I was referring to is that Naive is synonymous/close to dummy.

I'm very much in favour of avoiding non-inclusive terminology. I just don't think naive falls into that category based upon the dictionary. (I actually checked several and a thesaurus to base that opinion on)

But be that as it may. We're still looking for good names and given that there's resistance to NaiveDateTime we'll have to keep looking.

Preferably for a good name for LocalDateTime, though I'd not be opposed to keeping LocalDateTime.

How about Temporal.DateTime → Temporal.HumanDateTime? It's a date time in a human-readable calendar, the way humans think of it, without those pesky corrections for the fact that we live on a roughly spherical planet (time zones and daylight saving)

I agree with @pipobscure's reasoning that changing the name of DateTime would require us to change the name of the smaller classes. Even if a case could be made for Date and friends, at the very least, FooDateTime would imply renaming Time to FooTime since the current Time class does not contain a timezone.

Keeping this mind, I'd prefer renaming LocalDateTime as opposed to DateTime, because it would involve prefixing atleast two classes' names.

I actually strongly disagree with that reasoning, because there's no way to have a date without a time but with a time zone, or a time without a date but with a time zone, so I think it's slightly inconsistent but not ambiguous. And I think calling LocalDateTime "DateTime" is a valuable enough educational tool, suggesting "reach for this type," that it's worth the slight inconsistency.

I actually strongly disagree with that reasoning, because there's no way to have a date without a time but with a time zone, or a time without a date but with a time zone, so I think it's slightly inconsistent but not ambiguous. And I think calling LocalDateTime "DateTime" is a valuable enough educational tool, suggesting "reach for this type," that it's worth the slight inconsistency.

That's not correct. A date has a different meaning for Australia than for Britain because of the Timezone. Think of it as covering the entire span from midnight to midnight.

Just like we didn't have LocalDateTime we also don't have LocalDate though for consistency we probably should. (I just don't think it's worth it making things more complex since you can always implement LocalDate in userland if needed)

@ptomato I actually strongly disagree with that reasoning, because there's no way to have a date without a time but with a time zone, or a time without a date but with a time zone, so I think it's slightly inconsistent but not ambiguous. And I think calling LocalDateTime "DateTime" is a valuable enough educational tool, suggesting "reach for this type," that it's worth the slight inconsistency.

@pipobscure That's not correct. A date has a different meaning for Australia than for Britain because of the Timezone. Think of it as covering the entire span from midnight to midnight.

Just like we didn't have LocalDateTime we also don't have LocalDate though for consistency we probably should. (I just don't think it's worth it making things more complex since you can always implement LocalDate in userland if needed)

I actually agree with both of you in different parts of this argument. @pipobscure is correct that Date only has meaning in a time zone once it's been turned into an LDT. A Date without a time zone is comparable to a DateTime without a time zone. I also agree that implementing LocalDate and LocalTime are not needed.

But I also agree with @ptomato that "_it's slightly inconsistent but not ambiguous. And I think calling LocalDateTime "DateTime" is a valuable enough educational tool, suggesting 'reach for this type,' that it's worth the slight inconsistency._"

For me, this is the high-order bit. Date and Time are not ambiguous because we're not planning a LocalDate nor LocalTime. However, we will have both a zoned and zoneless date/time type, so there's inherent ambiguity in date/time types. Users will need to choose one or the other for each use case.

The problem is that we know that many developers may not fully understand the implications of this choice. So we want to nudge them with naming so that:
a) it's really clear which type is _not_ safe for DST and has no awareness of its timezone. Then developers who know what they're doing can pick or avoid this type for their use case.
b) developers who are ignorant or not paying attention or who don't know which to choose will pick the DST-safe type because its name is shorter/friendlier/familiar

A great example of this is my convo with Devon Govett (@devongovett) the maintainer of Parcel and a bunch of other useful OSS projects. He started by wanting for "ZonedDateTime/DateTime" but once he understood the types better, he ended up wanting for "DateTime/UnzonedDateTime". FWIW, at the moment Devon's choice is probably my currently top preferred name pair.

Here's the twitter link: https://twitter.com/devongovett/status/1308962338108702720. The threading is really weird so I had to hunt around to get all the replies. Hope I didn't miss any:

@devongovett I think DateTime/ZonedDateTime is clear enough. Is ZonedDateTime different from Absolute though? Just so you don’t need to store the timezone separately for formatting?

@justingrant Good questions. Need a few tweets to answer.
Re: "DateTime", many (most?) developers don't know how to write DST-safe code. So we want to nudge novices (via naming) to pick the DST-safe, knows-TZ type if unsure. This means a friendlier/shorter name for a zoned type vs unzoned.

@justingrant Yep. Another case: when devs don't know how stored data will be used later. Example: task scheduler which executes tasks in UTC. But what if a Scheduler GUI V2 wants to allow GUI editing in the original timezone? If stored already, it's easy.

@justingrant Re: "vs. Absolute", the zoned date/time type encapsulates an Absolute (now Instant), an unzoned DateTime (soon to be renamed), a TimeZone, and a Calendar (which is actually part of DateTime). Here's a diagram coming soon to the docs for explaining the relationship.
(I posted the updated object model graph here)

@justingrant
re: "Just so you don’t need to store the timezone separately for formatting?", it's more:

  • DST-safe math
  • DRY chained method calls
  • TZ edge cases like parsing far-future times stored before Brazil abolished DST
  • iCalendar/RFC5545 interop

@devongovett Ah yeah. Storing the timezone rather than an only absolute instant with local formatting could make sense when referencing future dates. Would avoid issues if timezone rules change in the meantime.

@devongovett In that case I change my vote to DateTime (includes zone) and UnzonedDateTime. I think using the word local is confusing because it may be in a different timezone from the user’s local timezone.

Just to be clear, I don’t object to

LocalDateTime -> DateTime
DateTime -> UnzonedDateTime

iff

Date -> UnzonedDate
Time -> UnzonedTime

because otherwise the named grouping of DateTime, Date and Time becomes inconsistent and suggests a correlation between (current) LocalDateTime and Date / Time.

So if the name of (current) DateTime is changed then the names of Date and Time also need to change.

I'm double-checking with the D&I team about "naive".

However, if we're going to add prefixes to types other than DateTime, I think we should stick with Civil. Everyone seems to dislike Civil when they first see it, but it is, without a doubt, the most precise term. Once people learn what Civil means, they'll get over their initial distaste for it (as I did).

I personally like DateTime/UnzonedDateTime, it makes very clear the difference, therefore what to expect to the instance.
Also, the "Local" part of LocalDateTime to me still kinda reminds me the idea of "local to the system", as in local environment.

We polled some possible names on Twitter. Below are the poll results from https://twitter.com/justingrantjg/status/1308619968632688640.

BTW, I checked the results every few hours after the poll started to see if there was a regional preference (e.g. developers awake in Europe/Asia vs. US) but didn't see any difference. After about 80 votes (before 8:00AM in USA) the results had a ratio of 2:1:3:12 and that ratio stayed consistent for the rest of the poll. There are still 3 days left but results have essentially stopped coming in. For future polls, we can probably make them 2 days long.

image

Respondents were also asked to reply with more details.

Justin Grant @justingrantjg
Follow-up: please reply & tell why you chose the names you did!
Also:

  • Are there other names you'd like better?
  • Did you like a pattern (e.g. ZonedXxxx vs. ZonelessXxxx, or Xxxxx vs. PrefixXxxxx) but not the names in that pattern?

https://github.com/tc39/proposal-temporal/issues/707 #tc39 #javascript

Here's the replies:

FranƧois Best - @fortysevenfx
I like the concept of Instants (a given point in time), however LocalInstant suffers in readability from the lowercase L followed by uppercase i. Events should be avoided because of DOM events confusion.

Nick Gard @ntgard
LocalInstant and Event are both great names for time+location data but I'd expect it to be more permanent, like a Lat/Long location. Locations can and do change timezones for political reasons. That's why I chose Zoned/Zoneless. Plus it's explicit

Sean Poulter @seanpltr
Instant with and without a TimeZone.

david Kaye (--The "K" stands for Quality) @dfkaye
TimeStamp and TimeZoneStamp

(((Jake Lambert))) @djakelambert
DateTime/AbstractDateTime
Or Time / AbstractTime. Keep it short and sweet.
Don't do Event, overloaded term. "ZonedDateTime" is unnecessarily long.
Very excited about this!

Devon Govett @devongovett
_(we had a multi-tweet back-n-forth, and the last one is below. See https://github.com/tc39/proposal-temporal/issues/707#issuecomment-699158773 for the full conversation)_
In that case I change my vote to DateTime (includes zone) and UnzonedDateTime. I think using the word local is confusing because it may be in a different timezone from the user’s local timezone.

_(note: I think someone mentioned this issue below in the previous champions' meeting.)_
Wollantine @wollantine
Zoned / zoneless look too similar to each other, to much cognitive load to differentiate.
I like LocalInstant because it's very unambiguous.

Josh Story @joshcstory
1/3 DateTime/ZonelessDateTime seem to fit the goals pretty well. The thing I’d most like to see is that these types not be comparable without explicit conversion so you are comparing instances of the same type
2/3 Related I think the use cases for ZonelessDateTime cross over into things like DatePartials. I may need to know when something happened but only be able to get year or month level precision. Having a type which carries a temporal precision could be helpful
3/3 The extension of this would be a DatePartial that had precision up to time but not zone is just one of the levels of precision

Nate Roling @nateroling
I like DateTime and NaiveDateTime myself. Naive implies just a little bit dumber, plus it’s hard to spell, making it less likely to be used šŸ˜‚

Steve Clay @mrclay_org
ZonedDateTime/AmbiguousDateTime

Daniel van Berzon @DvBerzon
1/3 Question. Do you mean a date with timezone information? Or an event that happened in a certain place? The concepts are importantly different. The date of the Apollo 11 moon landing can be expressed in London time, but it happened on the moon!
2/3 Which is why my instinct would be LocalDateTime and DateTime. It's important to think of the former as a date from the point of view an observer in a certain location.

Shane Carr @_sffc
The zoned type represents an event that occurred at a certain place on Earth.
The problem with LocalDateTime is that it means the exact opposite in Java: a date/time without a time zone. It doesn't seem friendly to developers to use conflicting terms when we can avoid it.

Daniel van Berzon @DvBerzon
3/3 I apologise for the extreme moon example, but there is an important distinction between the local time where an event happened, and just a localised time. You can express the time of a plane landing in Dubai in London time. The name should capture which it is.

Lord of the Files @density215
Using zone conveys the difference between the two the best for me and I feel newbies also need to deal with this concept ASAP. I could live with a less wordy suf|prefix, like DateTimeZ | DateTimeNoZ, though I can see confusion for newbies there.

Ari Porad @ariporad
a) I would have gone with Moment, but that’s already taken so maybe Instant? I like that they represent something concrete and specific.
b) Don’t have as good of an answer. Maybe Timestamp, because that’s advanced and nonspecific? Honorable mention to Instantish.

Jordan Harband @ljharb
tbh, I like "Event" but dislike "AbstractEvent". What about "Event/UnzonedEvent" or similar?

Darien MV @bhathos
1/2 I don’t understand Event. An event is an occurrence of something, so it follows that it happens or will happen beginning at a particular time*, sure ... but the event is still the thing that occurs, not the time it happens to do so.
* and not always in a single specific tz!
2/2 (Adding an extreme but famous example to illustrate this point for others —)
The Apollo 11 moon landing is an event. It occurred at a particular time, but not in a time zone, and new Event('1969-07-20T20:17:00Z') describes the event about as well as new Event({ people: 3 }).

jbr @jacobrothstein
For b), Elixir and rust’s chrono both have ā€œNaiveDateTimeā€ and I like what ā€œnaiveā€ connotes: ā€œThis might seem like a good idea, but you probably don’t actually want itā€

Michael Richardson @AnAccidentalDev
1/3 I dislike the use of "Event". I don't find that the name describes it well and it is too ambiguous. Seems that it could have a beginning and ending date/time, which does not seem to be the intention.
"Instant" has a much clearer definition for me.
2/3 In my mind
DateTime = just a date and a time. I immediately start looking for a better type.
Maybe we should call an unzoned date and time "UNSAFE_DateTime". That might encourage developers to use more appropriate types. šŸ˜‚
3/3 "LocalInstant" describes the intent, not just what it contains. Thumbs up I like the prefix "Local" for zoned types.
Something like "AbstractInstant" for a non-zoned date and time may help describe it's lack of connection to a frame of reference.

Graham Cox @grahamcox82
If it helps, in Java you have:

  • ZonedDateTime - knows it's timezone.
  • OffsetDateTime - knows it's zone offset but not the timezone.
  • LocalDateTime - doesn't know either.

There's also Instant, which is always in UTC, but that's semantically different.

Greg Bowler @g105b
All DateTimes have a timezone don't they?

Justin Grant @justingrantjg
Nope, e.g. SQL Server's DATETIME type is just a date & time. No timezone. A no-zone DateTime in JS is useful for interop with other systems, or for cases when zone isn't known or needed. Silly example: 4:20 on 4/20/20, a "holiday" that happens at the same time in all timezones.

Dzmitry Shymkin @dmitryshimkin
LocalDateTime/AbstractDateTime

Graham Cox @grahamcox82
Abstract in coding, especially in OO languages, normally indicates an abstract base class. Using it for a concrete type Will confuse people.

Jacob Bloom @mrjacobbloom
Zoned/Zoneless have my vote because the comparison being drawn is obvious no matter which type you're looking at. But I'd prefer a postfix over a prefix because it leads with the core of the functionality and not the details (though prefix is consistent w/ TypedArrays... hm...)

homer0 @homer0
DateTime seems to me like the more newbie-friendly, and I believe it should have zone/zoneless/unzoned to be anyone-friendly :P.

Here's my takeaways from the poll results and comments.

  • Obviously ZonedDateTime/ZonelessDateTime won in a landslide, but I'm not sure if that's because people liked the pattern or people liked those specific names. More investigation (probably a follow-up poll) can help with this.
  • Between the poll results (6%) and comments (e.g. "_Don't do Event, overloaded term._" ) I think we can safely exclude "Event" as a name.
  • Choices with "DateTime" in the name captured 83% of the results (94% if you include "DateAndTime").
  • About half the comments suggested mixing and matching the choices we offered, or pairing one of our choices with another name. Of those comments, the most common suggestions were mixing DateTime with a name that's not ZonelessDateTime:

    • DateTime/UnzonedDateTime

    • DateTime/NaiveDateTime (2 commenters -- apparently rust and Elixir use this)

    • DateTime/AmbiguousDateTime

So here's my conclusions based on this data:

  • We should limit follow-up investigation to names that contain "DateTime".
  • For the has-zone type: one of ZonedDateTime or DateTime seems like a winning choice
  • For the no-zone type, there's less consensus so this name seems up in the air. Esp. given that the winner of the first poll, "Zoneless" has some potential issues for non-English speakers, it seems worth a Round 2 for this name. UnzonedDateTime, NaiveDateTime, ZonelessDateTime all seem possible here. Shane suggested CivilDateTime above which seems worth testing too.

IMHO we should do one more round of polling to inform our answer to these two questions:

  • "ZonedDateTime" vs. "DateTime" for the zoned type?
  • "UnzonedDateTime" vs. "NaiveDateTime" vs. "ZonelessDateTime" vs. "CivilDateTime" for the non-zoned type?

I'll work on text for a follow-up poll and we can launch it on Monday/Tuesday, with the target of making a final decision by the end of this week. LMK if you want to see different questions/choices than what's proposed above.

I think we can/should exclude Zoneless/Unzoned because defining something by what it lacks is really bad practice and will not get consensus.

Based on the poll and @justingrant's analysis, I agree that it seems we should focus on names that include DateTime. Since the two-prefix poll option won out big over the one-prefix option, we should look at what prefixes are best.

I very much agree with @pipobscure that it's awkward to define something based on what it lacks.

So, my updated preference is ZonedDateTime and CivilDateTime, and also add Civil to CivilDate and CivilTime.

As @ljharb pointed out:

[datetime w/o zone] isn't ignorance of timezones, it's intentionally standing apart from them.

For this reason I think Zoned/Unzoned or Zoned/Zoneless are reasonable. I don’t think it’s a problem that the latter names communicate an absence because that absence really is its most important characteristic — it’s telling you the use case right up front. Though it might be unfortunate, the phrase ā€œdate timeā€ could as easily imply having a zone as not having one, so — especially given the ā€œzonedā€ one is what most people will need most of the time — I think it’d be pretty helpful to see immediately what to expect from each. Neither is more ā€œneutral,ā€ so both benefit from clear qualification.

FWIW I have to use ā€œunzonedā€ dates (without times) a lot in my current work. I don’t really understand things like ā€œUNSAFE_DateTimeā€ — it’s just a different concept, and sometimes it’s exactly what’s meant. Very much looking forward to the improving tool set, regardless of the names :)

@sffc I’m a bit confused by CivilDateTime. Isn’t that another term for ā€œzonedā€? Not an expert on this terminology by any stretch, but Wikipedia at least seems to corroborate that:

Modern civil time is generally standard time in a time zone at a fixed offset from Coordinated Universal Time (UTC) or from Greenwich Mean Time (GMT), possibly adjusted by daylight saving time during part of the year. UTC is calculated by reference to atomic clocks, and was adopted in 1972.

@sffc I’m a bit confused by CivilDateTime. Isn’t that another term for ā€œzonedā€? Not an expert on this terminology by any stretch, but Wikipedia at least seems to corroborate that:

I'm going by the Merriam-Webster definition, which doesn't mention time zone, as well as precedent in Golang: "Package civil implements types for civil time, a time-zone-independent representation of time."

I think of civil time as the time shown on a clocktower. A clocktower shows the hour and the minute, but it doesn't show the time zone. One must interpret the clocktower (civil time) in context to figure out the absolute timestamp.

I interpret the Wikipedia page as saying that civil time in modern use is interpreted alongside a fixed offset from UTC (as opposed to the position of the sun). You pair a civil time with a time zone in order to get the instant.

It's confusing, which is why we're having trouble arriving at a name.

Thanks, that makes sense I think! Or rather, it does, and I believe I now understand what you meant, but I also now finally get that there are two (or at least two?) very different usages of zoneless datetimes — and that up till now, I’d only been considering one, while you were speaking of another.

Because of the usage I’m familiar with, the MW definition (which even says ā€œsee standard timeā€) appears to support the notion that civil time ā€œhas a time zoneā€ (but what will be apparent shortly is that I’ve been using the word ā€œhasā€ to mean something different from you). In fact, so does the clocktower example. The clocktower doesn’t _show_ a time zone, but the time it shows _has_ one. It’s implicit, but specific. As you said, one must interpret the data in a particular TZ context (_one_ particular TZ context) because all the information wasn’t provisioned together. If I live one block from the clocktower, but (rather inconveniently) there is time zone boundary directly between my home and the clock tower, and one morning I wake up and groggily try to read the clock from my window — but I forget to make the usual one hour adjustment — I might subsequently be late to work. This is because interpreting the clocktower’s time using my local time zone led me to the wrong answer (for what the current instant was). This was possible because the clocktower’s time did ā€œhaveā€ a time zone. It just neglected to tell me what it was.

That idea — of a date time representation that doesn’t have a time zone because it’s _missing_ or unknown — is a perfectly sensible usage of zoneless date times, and one for which the term _civil_ seems very appropriate, too.

The reason it didn’t make sense to me, if it isn’t already apparent from how I was using the word ā€œhasā€ above, is that when I’ve deliberately worked with zoneless datetimes, they literally represented the notion of a date and time (or, often, just the notion of a date). This usage is like the cell on a calendar, but not like the face on a clocktower, because I can take a calendar to any time zone and freely reinterpret its cells through a local lens. The answers for what range of absolute times are represented by each cell will be different in each place, yet they are never incorrect. I think this usage, is if anything, nearly the opposite of civil time, even though both concepts, curiously, can be represented by the same {date, time} tuple of data — i.e. this can mean datetimes that _altogether lack time zones_ or it can mean datetimes which have been temporarily embarrassed by misplacing theirs :)

It’s possible that there’s no term which really encompasses both. They are different concepts that just happen to have the same data shape I guess, so maybe it is reasonable to just pick one (such as Civil) for the naming and leave some people confused by it, like I’d been.

So, my updated preference is ZonedDateTime and CivilDateTime, and also add Civil to CivilDate and CivilTime.

I second this!

I'd like to second the opposition to Civil as a prefix. Perhaps I'm in the minority here, but I had never heard of "civil time" before this discussion. Additionally, the intuitive definition of civil time would be the opposite of military time (ie. 12 hour time), which obviously is incorrect.

What about ZonedDateTime (or just DateTime) and FloatingDateTime? I think a floating time zone is a well-understood concept that matches this situation.

I support @bathos and @ljharb in that Zoned or Unzoned/Zoneless do strongly and clearly convey the main difference between the two classes.

I see two options though

  • DateTime + UnzonedDateTime(or ZonelessDateTime)
  • ZonedDateTime + DateTime

In both cases the name underlines an implicit preference of the expected behaviour of the main/newbie-friendly class, DateTime. Also, it reminds that if you want an unzoned instance you have to mindfully chose it.

I like ZonedDateTime/DateTime (and Date and Time). I think "civil" will be confusing.

I agree with UnzonedDateTime/ZonelessDateTime, but if the idea is to nudge developers into using DateTime with zone through naming, I fell like prefixing it is no the best approach. It might seem like You have an option between two different equivalent paths, instead of choosing a "default" or "exotic" path.

The aim is definitely NOT to nudge developers into using ZonedDateTime. It maybe the right tool for some tasks, but not the default anything.

And again definitions by absence (Zoneless/Unzoned) will not be acceptable.

I'd like to second the opposition to Civil as a prefix. Perhaps I'm in the minority here, but I had never heard of "civil time" before this discussion. Additionally, the intuitive definition of civil time would be the opposite of military time (ie. 12 hour time), which obviously is incorrect.

You are definitely not in the minority. The fact that no one knows what Civil means when they first see it is part of why it is a good name. You don't come in with any preconceptions. You take a couple minutes to read up on what it means, and your vocabulary has expanded. Dates are complicated, and you've just learned something new and important about them.

What about ZonedDateTime (or just DateTime) and FloatingDateTime? I think a floating time zone is a well-understood concept that matches this situation.

"Floating" is a new suggestion that seems plausible.

@ljharb I like ZonedDateTime/DateTime (and Date and Time)

This is the only pattern that I'm strongly opposed to, because it will encourage accidental use of the zoneless date/time type by developers who may not be aware of the consequences of inappropriately using a zoneless type.

For example: at my previous company the recent-grad founders used the (zoneless) C# DateTime type and the (zoneless) SQL Server DATETIME type to build the company's software. The result: all date/time values were implicitly stored in America/Los_Angeles which was the system time zone of the original back-end server. Twice per year there were DST problems, scaling internationally was painful, and years later when I joined the company we had to spend $400K+ USD in scarce developer time to rewrite the back end to use UTC.

It's unlikely that this would have happened in Elixir where the zoned type is called DateTime and zoneless type is called NaiveDateTime. I'm not suggesting that JS needs such a strong signal as "Naive", but calling the zoneless type "DateTime" would be an invitation to inexperienced developers to choose it for use cases where it may not be appropriate.

I'm not saying to drop the zoneless date/time type--there are important use cases for it per #948--but given that we'll have a pair of date/time types, we should try to make the zoned name friendlier and shorter to reduce accidental use of the unzoned one.

I don't have a strong opinion about the unzoned type's name as long as it's not something that a naive developer would accidentally choose. Any of UnzonedDateTime, NaiveDateTime, FloatingDateTime, PlainDateTime, or probably 50 other names seem OK to me.

@sffc So, my updated preference is ZonedDateTime and CivilDateTime, and also add Civil to CivilDate and CivilTime.

I don't think it's a good idea to use the same prefix for the (unzoned) date/time type as we use for the Date and Time types. If I have a Date and I want to convert it to a date/time type, then IMHO the language (via naming) shouldn't encourage me to favor the unzoned date/time type. Otherwise we can end up with the same problem described above: developers accidentally choosing the wrong type for date/time use cases when the language makes "unzoned" the easiest and most intuitive path. Also, adding a prefix hurts brevity which we know is a top concern for many developers.

I don't think it's a good idea to use the same prefix for the (unzoned) date/time type as we use for the Date and Time types. If I have a Date and I want to convert it to a date/time type, then IMHO the language (via naming) shouldn't encourage me to favor the unzoned date/time type. Otherwise we can end up with the same problem described above: developers accidentally choosing the wrong type for date/time use cases when the language makes "unzoned" the easiest and most intuitive path. Also, adding a prefix hurts brevity which we know is a top concern for many developers.

And this is where we disagree hard. DateTime, Date & Time will have the same prefix (or none). Contrary to your conviction the Unzoned types should not necessarily be explicitly favoured, but neither should a zoned type. It depends exclusively on what they are. And Date & Time are both unzoned as is DateTime and their names should reflect that.

I'm not saying to drop the zoneless date/time type--there are important use cases for it per #948--but given that we'll have a pair of date/time types, we should try to make the zoned name friendlier and shorter to reduce accidental use of the unzoned one.

This might have been already discussed and decided, but despite my research throughout all the issues (and @justingrant's effort) I can't seem to find a good 100% convincing answer to this.

_Why instead not just drop the zoneless type and force developers to define a TimeZone or default to UTC?_

If you need a representation of a Date or Time or ZonelessDateTime you can still use a UTC instance of the LocalDateTime for all of them without issues and the whole confusion about the type to use would be steered towards understanding/choosing the appropriate timezone for the use case, which is a very important concept anybody working with dates should be at least aware of anyway.

Honestly, I still can't see any difference (i.e. what can/can't you do or represent with one or the other) between for example

const date1 = Temporal.DateTime.from('2020-01-03T19:41:00-07:00');
const date2 = Temporal.LocalDateTime.from('2020-01-03T19:41:00Z');

UTC represents a real place - it’s not some ā€œplaceholder timezoneā€. Being able to represent a date and time where UTC is critical information is very different from being able to represent one where the time zone is not part of what’s represented.

And beyond what @ljharb said:

There’s also a zoneless Date, which would be wrong in UTC, since the date means a different timespan in Australia and England.

There’s also a zoneless Time which represents up to ~24 different times depending o. which zone it is ultimately in. (Think new-year which happens at 0:00 anywhere in the world)

In short they are just very different concepts and to repeat @ljharb UTC is not an empty placeholder, it’s a real thing.

It has been my experience that having date-and-time datatypes that give you observer-independent-orderability is most useful to avoid bugs. What i mean by this is regardless of the observers place in time/geo two any observer will agree on whether one instance is before/after/same-as another.

using something like Instant which gives you an offset from unix epoch gets you pretty far here but there are problems with describing times far into the past (or really far into the future)

The discussion around DateTime/ZonelessDateTime seems to circle around DateTimes (with a timezone) that preserve orderability which is good. but they also convey a "where" carried by the chosen timezone. By suggesting you use UTC as a default I believe the idea is that for use cases where orderability is what matters but a preferred reference frame (the "where") does not.

is 2020-01-01T00:00:00-01:00 the same as 2020-01-01T01:00:00-00:00?
If we are only concerned with orderability then yes they are
If we are concerned with whether these times have the same "where" then no they are not

From feedback on this thread I'm not sure everyone is in agreement about the goals of this datatype (i certainly am not sure myself) and so it can be hard to understand how to interpret feedback consistently

@joshcstory I see where you are coming from, but you are missing about 90% of all use-cases and by extension considerations.

I’m now going to lock this issue, since there have been few new perspectives added. I think we’ll just have to make a call some time.

This issue is now unlocked, but the proposal champions have a favor to ask: let's keep this issue focused solely on the final naming of the Temporal types currently named DateTime (date/time without time zone) and LocalDateTime (date/time with time zone).

If you have other feedback about the Temporal API or other questions about Temporal, we're eager to hear them but please open a new issue so we can keep the discussion here focused on naming these two types. Thanks!

FYI, here's what other languages and platforms call their zoned and unzoned date/time types. I don't know most of these platforms well, so I'm hoping I understood their documentation correctly! Please correct me if I got any of these wrong.

| API | IANA-Zoned Date/Time | Unzoned Date/Time |
| --------------------- | ---------------- | ------------------ |
| Java / Kotlin | ZonedDateTime | LocalDateTime |
| Joda | DateTime | LocalDateTime |
| Rust | DateTime | NaiveDateTime |
| Elixir | DateTime | NaiveDateTime |
| Go | Time | DateTime (in civil package)|
| Swift | (none) | Date |
| .NET | (none) | DateTime |
| SQL Server | (none) | DATETIME / DATETIME2 |
| Oracle | (none) | TIMESTAMP WITHOUT TIME ZONE |
| Postgres | (none) | TIMESTAMP WITHOUT TIME ZONE |
| MySQL | (none) | DATETIME |
| Python | datetime | datetime |
| Boost (C++) | local_date_time | date_time |

Notes:

  • APIs released in the last 10 years all have zoned types, except Swift whose date/time library is just a shim over the older Objective C one. None of the older APIs have one. Java.time is the reverse: an old platfom whose date/time API is only 6 years old.
  • I included Joda because Java's API is based on it, and most other modern APIs have been inspired by it.
  • Many of the older platforms use DateTime/DATETIME/datetime for the unzoned type, but none of the newer platforms have an unzoned type called "DateTime".
  • Some of these (.NET, SQL Server, Java) have a date/time/offset type but not an IANA-zone type.
  • Python does have the ability for the datetime type to use time zones, but there's no built-in IANA support. You'd need a 3rd-party library for that. Python also calls zoneless types "naive types" and zone-ful types "aware types'.
  • Oracle and Postgres have a "TIMESTAMP WITH TIME ZONE" type, but it doesn't actually store the time zone. It's just a way to indicate that literals should be allowed to have timezone info (either offsets or IANA zones) and that, when the column is displayed, it should be displayed using the session's current time zone. The actual storage is just a UTC timestamp.
  • Boost has a nice description for zoned time: "A time measured in a specific location of the universe."
  • Python only recently (Python 3.9) added IANA time zone support.

Let’s add C++/Boost to that list:

IANA-Zoned: local_date_time
Unzoned: date_time

Given that there are examples in pretty much any direction, it’s become clear to me that there is no right answer to this. So I’m looking for some API design principles we can use to make the call. I’ll put some forward but am asking for more:

  • positive naming only: name something by it’s attributes or what it is, never by what it is not or an absence. (consequence: unzoned/zoneless violate this)

  • group related classes by name: if a set of classes represent the same kind of thing they should be named similarly. (consequence: if DateTime gets a prefix, so does Date and Time.

  • perfect English is not required: pay attention that names are not confusing to people with less than perfect English. (example/consequence: Local & Locale could lead to LocalDateTime or LocaleDateTime and they are interchangeable to the non-native speaker.)

@pipobscure Your 3 principles look good to me. I don't agree with the first one, but not strongly because there are other good positive choices for that name. So all 3 principles are OK with me.

I'd add two more which I'm not sure if we agree on:

  • If users aren't sure which date/time type to use, gently encourage them to try the zoned type first. Why? If a developer picks the zoned type incorrectly, then it's trivial to realize the mistake when the code runs the first time. However, if a developer accidentally picks the zoneless type, then it's easy to miss the mistake until production code breaks at DST transitions. The latter is riskier for the ecosystem, so IMHO we should gently nudge users to try the zoned type first. I think a gentle nudge would be more appropriate than a shove like "NaiveDateTime" of Rust and Elixir, which seems kinda extreme to me.

  • Try to keep APIs short, because our top early-adopter feedback has been for more brevity

  • (consequence: if DateTime gets a prefix, so does Date and Time.

I agree with the principle 100%. But I followed it to different conclusions. I see "related" meaning "things so closely related that developers may be be confused about which to use". The two date/time types are that closely related. They need similar names. But for more distant relationships like Date, I don't see how the brevity hit is worth it. MonthDay is closely related to Date but we don't call it MonthDayInDate because there's no ambiguity so the extra context isn't worth the cost.

A shared prefix would also increase the risk of accidentally using a zoneless type.

Let’s add C++/Boost to that list:

Done!

On Go, the package civil (which is released by Google) is where you find the zoneless DateTime type.

Just to clearly state my preference:

LocalDateTime: has IANA zone. This also means it is correctly interpreted when Local == Locale in one's vocabulary.

NaiveDateTime/NaiveDate/NaiveTime: does not have TZ information and the prefix gives people a shove to pick wisely.

MonthDay/YearMonth: are really only tuples where the name describes their content. They only relate to NaiveDate in that they are less competent (maths/calendar translation) so they don't need the prefix. (if we were to call MonthDay something like Holiday then it would need the prefix).

Can we check around to determine if Naive is an option or not. I'd think it is, but then I'm a fully able white male so possibly not the best person to make that determination.

(Maybe do a twitter poll to find out. Given that it's a clear and binary question it lends itself to that mechanism)

My preference at this point: DateTime (for the zoned type), XxxxxDateTime (for zoneless), Date, and Time.

As long as Xxxxx is not '' then I'm probably OK with it as long as it's popular on Twitter and TC39 is OK with it. Weakly held (1/5) opinions: shorter and easy to spell is helpful, e.g. Civil or Plain. I like Naive personally although I worry it might be hard to spell for non-English speakers.

My strongest opinion (5/5) across all of Temporal (not just this issue) is that the zoneless type should NOT be called "DateTime" because a prefixless name will be novices' first-choice type, which should not be zoneless.

re: Date/Time prefixes, I don't personally care that much but I expect other people (e.g. the developers sending brevity feedback) to be very unhappy with this. I'm not convinced of the value of the prefixes on Date and Time outweighs the pain we'll be causing brevityphiles. For the two date/time types we need at least one prefix. But anything beyond that will feel probably feel unnecessary and annoying to a lot of our users. So 4/5 for no prefixes on Date and Time.

re: zoned type name, I think Joda and Java's use of LocalDateTime for a zoneless type makes LocalDateTime a non-starter for a zoned type. 5/5. It's unnecessarily confusing to Android developers (e.g. React Native) and Java developers overall. Instead, I'd prefer (3/5) to do what Rust and Elixir are doing: make DateTime (aka "newbies start here") the zoned type. If that won't fly, ZonedDateTime also seems OK, as long as the zoneless type isn't called "DateTime"! ;-)

And I guess that's where we disagree.

I'd state "if there is any type called DateTime then it is the zoneless type. anything else turns the nudge toward making an informed decision into a shove toward using the zoned type, which I believe to be fundamentally wrong."

Though I'd be fine fine with ZonedDateTime, NaiveDateTime, NaiveDate and NaiveTime.

(P.S.: despite feedback, I am still of the opinion that clarity trumps brevity 100% of the time)

_I keep trying to post this comment and @pipobscure keeps replying with good answers and each time I had to revise! Arrrgh. ;-) But good progress. We'll make more tomorrow I'm sure. Talk wtih you in a few hours!_

Here's a summary of my understanding of consensus and open issues re: naming the zoned and unzoned date/time types. I tried to put the open issues in the order that seemed most likely to lead to consensus, but feel free to re-order when we discuss. This is a long thread to summarize so I'm sure I missed something. Let me know mistakes and I'll fix.

Has Consensus

  1. Names for these types should include the word "DateTime" per the poll results
  2. The names "ZonedDateTIme" (poll winner) and "DateTime" (poll distant 2nd place) seem to be the finalists for the zoned type. This name ironically seems less contentious than the unzoned one.
  3. The poll winner "ZonelessDateTime" should NOT be used for several reasons including concerns about similar prefixes confusing non-English speakers and concerns about using negation in a type name.

No Consensus Yet

  1. Which principles to use? This is making sure we agree with Philipp's principles and also how folks feel about the other two I suggested to add.

  2. How opinionated should the names be? For brand-new users, what type do we want them to try first if they're not sure which one they need? The answer of this question isn't what names we want, it's what _kind_ of names we want-- the pattern.

  3. 4.1 Unopinionated names like Java? (which uses ZonedDateTime / LocalDateTime)
  4. 4.2 Mildly opinionated names like Joda? (which uses DateTime / LocalDateTime). This pattern is my preference, at 3/5.
  5. 4.3 Very Opinionated names like Rust and Elixir? (which uses DateTime / NaiveDateTime)

  6. Should Date, Time, YearMonth, MonthDay get prefixes too?

  7. 5.1 Yes, because Date, Time, etc all don't have time zones. A common prefix may also help to teach users about the difference between absolute time and clock time. (I don't think I understand the advantages of this option very well, so feel free to suggest more.)
  8. 5.2 No, because the only types closely related enough to absolutely need a similar name are the two date/time types. Also, many developers will dislike typing prefixes that they'll see as unnecessary. Also, we don't want developers converting from Date to accidentally use a zoneless type. This option is my preference (4/5).

  9. What to call the unzoned type?

  10. 6.1 This one may depend on the decisions above.
  11. 6.2 Names that don't have any objections AFAIK: PlainDateTime (distant 2nd in poll), FloatingDateTIme (not polled)
  12. 6.3 Several folks are concerned that CivilDateTime would be confusing. Shane sees this as a feature not a bug because it encourages users to learn what "civil" means.
  13. 6.4 Several folks are concerned that UnzonedDateTime shouldn't be used because APIs shouldn't be named after what's missing. I disagree but only 2/5 because other names are OK too.
  14. 6.5 My strongest opinion (5/5) across all of Temporal (not just this issue) is that the zoneless type should NOT be called "DateTime" because a prefixless name will be novices' first-choice type, which should not be zoneless.
  15. 6.6 Other than not being called "DateTime", I'm OK with any name that's popular and TC39 doesn't veto. Weakly held (1/5) opinions: shorter and easy to spell is helpful, e.g. Civil or Plain. I like Naive personally although I worry it might be hard to spell for non-English speakers. Floating might confuse folks with "floating point".

  16. What to call the zoned type

  17. 7.1 This one should be relatively easy once we resolve the ones above. ZonedDateTime and DateTime are the contenders. My preference (3/5) is for DateTime because it will be a safer honeypot for novice guesses, but I'm OK with ZonedDateTime too as long as the zoneless type isn't called DateTime!
  18. 7.2 LocalDateTime for a zoned type is not OK (5/5) because that name is used for the zoneless type in Java and Kotlin.

In PHP there is only a zoned DateTime class, if you want to add it to the API list.

I think the discussion on the naming could (sbhould?) just actually reduce to deciding Zoned vs Zoneless names.
That is exactly the way everybody here (in this and other threads lately), maybe even without realizing it, referred to the two types. In fact, that describes very clearly and unmistakably their difference.

This would make an effective additional (final?) survey tweet:

  • DateTime + ZonelessDateTime
  • DateTime + ZonedDateTime
  • ZonedDateTime + ZonelessDateTime

which would indirectly provide information about the "expected" behavior, in terms of time-zone/DST handling, of a date/time class.

Meeting 2020-10-02:

  • ZonedDateTime for zoned type
  • XxxxDateTIme, XxxxDate, XxxxTime
  • Prefixes on unzoned DateTime, CIvil vs Naive vs. Plain vs. Floating
  • Conversion methods are to followed by the full type name.

ugh, a prefix for DateTime and friends seems like a lot of extra boilerplate, regardless of what it is (not "naive" tho, regardless). why can't they just be DateTime/Date/Time?

We need the prefix or people will just use DateTime and be blindsided by it not doing timezones. But calling ZonedDateTime without a prefix muddles the waters and leads to the opposite problem.

define:naive => natural and unaffected; innocent

but we decided to leave that to a twitter poll, to get feedback from the community.

Why would they be blindsided? if they have a timezone, they'd provide it and get an error; if they don't, then it'll be the right term.

Regarding "naive", TC39 doesn't make decisions by polling, and I find that name unacceptable, regardless of polling results.

It's more about what if they have a timezone (in another db field) and choose DateTime by forgetting its there.

Can you explain your reasoning for naive being unacceptable. Especially since the definition is what I gave abpve and both Rust & Elixir chose it.

We've talked about it on other threads. The connotation is something I find offensive, regardless of what descriptive meaning the dictionary has attempted to prescribe.

Ok, there’s some unspecified connotation. By the same token one could
object to ā€œclassā€ which connotes an artificial and unequal social
distinction, realms which connote monarchy, WeakRefs which connote an
ableist lack of stamina, oh and anything containing natural which since
Shakespeares time connotes something of a lack of intelligence. And all
that despite them being used in ECMAScript and elsewhere including recently.

I guess we’ll just have to accept that and object to all such usage in
future as well. Including the term brand as in brand-check given it
connotes violence against sensate creatures.

On Fri, 2 Oct 2020 at 18:29, Jordan Harband notifications@github.com
wrote:

>
>

We've talked about it on other threads. The connotation is something I
find offensive, regardless of what descriptive meaning the dictionary has
attempted to prescribe.

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/tc39/proposal-temporal/issues/707#issuecomment-702861590,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AADM5L4SUOBAMNJTKZPBXFDSIYEYJANCNFSM4OI7RDCA
.

Adding a prefix to all three types (XxxxDateTime, XxxxDate, XxxxTime) wasn't easy to agree on, but we decided to move forward on that assumption for now and gauge the degree to which the community and the committee strongly disfavor that approach.

There are a lot of reasons why the prefix makes sense. Here are a few:

  1. Emphasizes that ZonedDateTime and XxxxDateTime/XxxxDate/XxxxTime are two different "realms" in Temporal.
  2. Leaves open the option for third-party libraries, or a potential Temporal follow-up, to add ZonedDate and ZonedTime, which are both well-defined on their own.
  3. Minor: Further reduces potential confusion between legacy Date and Temporal.Date. The Temporal prefix already eliminates most of this confusion, but the names being the same may still be confusing to some programmers.

@pipobscure slippery slope arguments aren't particularly helpful in these kind of discussions, nor do they come off as being in good faith.

I'll leave it up to others and Twitter to argue about specific prefixes. I don't have a strong opinion although I don't like "naive" either because spelling, connotation, etc.

I'd also strongly prefer (although I was outvoted and don't want to block consensus) no prefix on Date nor Time because I'm concerned that brevity-oriented developers will hate the extra typing and because a prefix isn't strictly needed for disambiguation unlike the two date/time types where at least one must be prefixed.

The only would-block-consensus opinion I have in this discussion is that the zoneless date/time type needs a prefix and should NOT be called "DateTime" w/o a prefix. Here's why:

@ljharb Why would they be blindsided? if they have a timezone, they'd provide it and get an error; if they don't, then it'll be the right term.

The problem is that most developers won't get an error. They'll supply the time zone and it will be ignored, or they won't even realize that the time zone is needed because their linter and/or TS didn't warn them. Instead, their zoneless code will appear to work fine and will pass tests. Then the code will break in production when a DST transition happens. That's bad! Copying from my comment above:

If users aren't sure which date/time type to use, [we should] gently encourage them to try the zoned type first. Why? If a developer picks the zoned type incorrectly, then it's trivial to realize the mistake because [the code will crash on first run]. However, if a developer accidentally picks the zoneless type, then it's easy to miss the mistake until production code breaks at DST transitions. The latter is riskier for the ecosystem, so IMHO we should gently nudge users to try the zoned type first.

TL;DR - if a developer is not sure which type to pick, choosing the zoned type is vastly safer for the developer and for the ecosystem overall because finding "I chose the wrong type" bugs are caught at development time instead of in production.

A sample use case is a "last call skill" on a smart speaker which will automatically announce "last call!" 15 minutes before closing time at a bar. On the Saturday night where DST starts each Spring, a 2:00AM closing time becomes 3:00AM. With the Temporal zoned date/time type, I (correctly) hear the reminder at 1:45AM because the zoned type knows that subtracting minutes should use exact (Instant) math as required by RFC 5545 which is the controlling spec for DST-safe calendar math. However, If I use an unzoned Temporal type, subtract 15 minutes, and then convert to Instant to schedule the reminder, then last call will happen at 3:45AM! Without a unit test for DST transitions, it's likely this bug will never be found before shipping.

Also, in almost every platform that I surveyed, the name "DateTime" means "the date/time type we want developers to try first if they don't know which type to pick." To avoid bugs like the last-call example above, all* surveyed platforms with a zoned date/time type DON'T offer an unzoned type named "DateTime" because they don't want naive users accidentally choosing the unzoned type by default. The (more opinionated) Rust and Elixir named their zoned type "DateTime" while the (less opinionated) Java doesn't have a type named "DateTime". My preference is to follow Elixir/Rust's pattern, but consensus was to be less opinionated like Java which I'm OK with. IMHO, the only really bad outcome would be to make the "default" name (aka DateTime) be zoneless.

_* except the boost C++ library which probably has relatively little overlap with JS developers_

@justingrant hmm, why would the zone be ignored? i'd expect it to be an error if i try to provide a timezone to an unzoned type.

Leaves open the option for third-party libraries, or a potential Temporal follow-up, to add ZonedDate and ZonedTime, which are both well-defined on their own.

@sffc what would be the purpose/use of a ZonedTime? Maybe, just guessing, a wall-clock that automatically updates with DST? But and how can you define such class if, by definition, it doesn't include a date (otherwise it would be a ZonedDateTime), which is what allows you to determine when to switch?

Same thing for ZonedDate, how is it different in behavior/results than a Date? If it had a timezone it would be a ZonedDateTime, wouldn't it?

Leaves open the option for third-party libraries, or a potential Temporal follow-up, to add ZonedDate and ZonedTime, which are both well-defined on their own.

@sffc what would be the purpose/use of a ZonedTime? Maybe, just guessing, a wall-clock that automatically updates with DST? But and how can you define such class if, by definition, it doesn't include a date (otherwise it would be a ZonedDateTime), which is what allows you to determine when to switch?

Same thing for ZonedDate, how is it different in behavior/results than a Date? If it had a timezone it would be a ZonedDateTime, wouldn't it?

@pipobscure can answer this better than me, but a ZonedDate is a span of time lasting a whole calendar day in a time zone, and a ZonedTime is an incomplete piece of information that makes sense once paired with a XxxxDate. For example, nationally broadcast primetime events in the United States typically begin at "9pm America/New_York", a ZonedTime.

The claim is not that these types are particularly useful. They aren't being proposed for inclusion in Temporal. However, they illustrate the difference in realms between types with time zones and types without time zones.

@pipobscure can answer this better than me, but a ZonedDate is a span of time lasting a whole calendar day in a time zone

Isn't that though a "period" concept though, like somehow (arguably) similar to Duration? I mean, it's a different concept from a Date, which would imply a different name/class (say Period/ZonedPeriod).
This just to confirm that to me a ZonedDate or ZoneTime still does not really make sense. šŸ˜…

@justingrant hmm, why would the zone be ignored? i'd expect it to be an error if i try to provide a timezone to an unzoned type.

@ljharb JS usually doesn't complain if extra data is provided in a method call.

dt1 = Temporal.DateTime.from('2020-03-08T01:00-07:00[America/Los_Angeles]');
dt2 = Temporal.DateTime.from({ year: 2020, month: 3, day: 8, hour: 1, timeZone: 'America/Los_Angeles' });

Neither of the lines above throw an exception or provide any indication that there's a problem at development time or at runtime until the user tries to derive a new value (e.g. adding 2 hours) near a DST transition.

But the case above is the easy case. A harder case is when developers don't realize that a time zone is needed because they're not thinking of DST edge cases and what can go wrong. An even harder case is where developers know a timezone is needed and use a timezone, but they commit order-of-operations bugs like @ptomato did in #698. And he's an expert! The median developer is far worse and commits these kinds of bugs frequently.

With a zoned type these kinds of bugs are almost impossible to commit, because a time zone is required and DST best practices are baked in to the implementation. Once you've successfully created a ZonedDateTime (new name for LocalDateTime as of today), then you're guaranteed that subsequent derived values (e.g. with plus, minus, difference, with, etc.) will be created in a DST-safe way in the same time zone. This is the reason why most newer platforms have chosen to follow the lead of Joda Time which pioneered this "zoned type" approach about a decade ago.

JS doesn't complain if unknown data is provided - however, the dateStyle/timeStyle precedent imo suggests that when known and incorrect data is provided, an exception is ideal and warranted. In this case, it seems like making the unzoned types throw when a timeZone is provided would address the usability concerns, since it'd be impossible to accidentally make an unzoned type when you wanted a zoned one, and if you don't want a zoned one, then the unzoned type is likely correct.

Hey! Sorry to interrupt, but I don't think anyone's brought this up yet: I keep misreading "naive" as "native" (a word I see far more often day-to-day), which gives me the impression that the difference between these two types is that one is "native" (to the OS?) and the other one is... userland/3rd-party? Not sure whether this misreading is common or specific to me but I thought I'd mention it

when _known_ and incorrect data is provided, an exception is ideal and warranted.

@ljharb Currently, Temporal doesn't consider extra fields as "incorrect" because there are valid use cases for extracting partial data from an ISO string or property bag. One common example is when the same storage is shared among multiple consumers. For example, 2020-03-08T01:00-07:00[America/Los_Angeles] stored in a database column with three consumers:

  • A reporting app only cares about the date
  • A back-end microservice only cares about the instant
  • A UI only cares about the human-readable date and time

Today all of those cases can call from on Date, Instant, and DateTime respectively without errors. Other use cases include handling mixed inputs (e.g. some have a date & time, some only a date) or migrating from one storage format to another without breaking clients. Another case we may support (see #933) is parsing formats with some components omitted, e.g. date+timezone, or date+time+timezone without offset. Another case is Calendar.from and TimeZone.from being able to parse the timezone (only) or calendar (only) from an extended ISO string like 2020-03-08T01:00-07:00[America/Los_Angeles][c=japanese].

it seems like making the unzoned types throw when a timeZone is provided would address the usability concerns, since it'd be impossible to accidentally make an unzoned type when you wanted a zoned one, and if you don't want a zoned one, then the unzoned type is likely correct.

We could make parsing stricter only for the time zone and only for the from and with methods of the unzoned type. This would be inconsistent but it would help the failure case you noted. But AFAIK that failure case is relatively unusual.

The harder and more common problem is that many developers won't _know_ that they should be using the zoned type for many use cases, because DST-safe programming is confusing and the unzoned date/time type usually works OK in a dev environment or CI. Problems generally crop up only in production and only around DST transitions (or other time zone definition changes like when Brazil abruptly decided to stop using DST) which are intermittent, dependent on geography, and not usually covered by test automation.

This is why modern date/time APIs across multiple platforms generally avoid giving a "default-sounding" name ("DateTime") to the zoneless type, because a large % of developers won't intuitively expect to need a zoned type for many use cases. Cues from the names are helpful to guide novices to the correct type.

I agree, and regardless of the names, some errors like we’ve discussed would ensure they immediately and always get an error pointing them in the right direction. That way, because no matter what names we pick, there will be confusion, the underlying problem is actually solved.

In other words, yes, the names should be descriptive, but the usability argument imo doesn’t apply to naming if we have good errors for these cases.

We had these discussions in detail. We very much considered different ways
of handling these issues and came to this conclusion after very careful
consideration.

While I’m happy to go through some of the reasoning, and it’s preserved in
the minutes of meetings, I don’t think it’s particularly helpful do
relitigate this here. Am I the only one of that opinion?

On Sat, 3 Oct 2020 at 00:25, Jordan Harband notifications@github.com
wrote:

>
>
>

I agree, and regardless of the names, some errors like we’ve discussed
would ensure they immediately and always get an error pointing them in the
right direction. That way, because no matter what names we pick, there will
be confusion, the underlying problem is actually solved.

In other words, yes, the names should be descriptive, but the usability
argument imo doesn’t apply to naming if we have good errors for these cases.

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/tc39/proposal-temporal/issues/707#issuecomment-702998615,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AADM5L4X2NVGPS5QGTNTGF3SIZOOVANCNFSM4OI7RDCA
.

Hi @ljharb - There's a lot of back-n-forth so I want to make sure I understand your feedback. A few short questions to clarify:

1) You're suggesting that Temporal.DateTime.from should throw if a time zone is present in the input. Are you also suggesting that from of _all_ Temporal types should throw if additional data is present beyond what that type can represent? (This change would break a bunch of use cases and/or make them more difficult.)

2) Are you supportive of excluding the unprefixed name "DateTime" from possible names for the unzoned date/time type, per discussion above about the problems of accidental use of the unzoned date/time type? If not, why not?

3) if (2) is "yes", then DateTime will have a prefix. We're currently looking at Naive, Plain, Floating, and Civil for those prefixes. I know you really don't like "Naive". Are there any _other_ names on the shortlist that you think are so bad that you'd want to block even if it turns out that Twitter loves them?

4) if (2) is "yes", then DateTime will have a prefix. Are you OK with the same prefix on Date and Time per the team's consensus today?

5) Is there any _other_ feedback that you've been trying to get across re: naming these date/time types that's not captured by the 4 questions/answers above?

  1. Only the unzoned types, and only if a timezone is provided.
  2. I’d prefer no prefix at all.
  3. If there is a prefix, I’d prefer Local, Plain, Civil, i suppose.
  4. I also think it’s better if Date and Time are unprefixed, even if DateTime is prefixed.
  5. I think the only thing that may not be coming across is that if 1 happens, i think the possible accidental use of an unzoned type stops being a problem, which means it doesn’t have to be part of the decision about a prefix.

@ljharb thanks for the feed back.

Given that we had this very discussion yesterds as well as last week, and
after careful consideration reached conflicting conclusions, makes me think
reading and following the arguments made may well lead you there as well.
Can I invite you to read the minutes of these meetings and then come back
to the discussion? I am also happy to sit down (virtually) with you and
explain the rationales.

Until then, I don’t really know what to do based on that feedback. These
things were considered and discussed at length and that was necessary for
us to reach this consensus. Many of us started out at many different places
including agreeing with you. So that I have to assume that actually
following the reasoning would move your point of view into agreement with
the decision as it stands now.

And that in turn would mean the right thing to do is to utterly ignore what
you’re saying, which I’m not willing to do. So what would be a good process
to engage here?

On Sat, 3 Oct 2020 at 02:13, Jordan Harband notifications@github.com
wrote:

>
>
>
>
>
>
>

  1. Only the unzoned types, and only if a timezone is provided.

  2. I’d prefer no prefix at all.

  3. If there is a prefix, I’d prefer Local, Plain, Civil, i suppose.

  4. I also think it’s better if Date and Time are unprefixed, even if
    DateTime is prefixed.

  5. I think the only thing that may not be coming across is that if 1
    happens, i think the possible accidental use of an unzoned type stops being
    a problem, which means it doesn’t have to be part of the decision about a
    prefix.

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/tc39/proposal-temporal/issues/707#issuecomment-703020597,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AADM5L3UBNVIETBIE7QPL53SIZ3CRANCNFSM4OI7RDCA
.

Finally catching up after the usual weekly flurry of comments in this repo. Excuse the haphazard replies to different comments. šŸ˜„

Python does have the ability for the datetime type to use time zones, but there's no built-in IANA support. You'd need a 3rd-party library for that.

Extra data point for completeness — that's no longer true as of Python 3.9: https://www.python.org/dev/peps/pep-0615/

(P.S.: despite feedback, I am still of the opinion that clarity trumps brevity 100% of the time)

I am definitely on @pipobscure's side here. I get the brevity argument, and it is important, but IMO it's not _as_ important as being consistent.

Given that we had this very discussion yesterds as well as last week, and
after careful consideration reached conflicting conclusions, makes me think
reading and following the arguments made may well lead you there as well.
Can I invite you to read the minutes of these meetings and then come back
to the discussion?

@pipobscure I know your reply was to @ljharb, but are those meeting notes available for anyone else to see as well? There are plenty of non-TC39 people who have commented on this issue, who might be interested in the arguments that were made. The meeting notes section of the repo hasn't had any new content in months.

The meeting notes section of the repo hasn't had any new content in months.

I was thinking about this as well, I'll update it later today.

Notes PR up at #959

Notes PR up at #959

Thanks @ryzokuken! The minutes with this discussion are here: https://github.com/tc39/proposal-temporal/blob/869bdc253ce35ba85166c913168f2dd8136fe356/meetings/agenda-minutes-2020-10-01.md
Look for the heading "_What should be the long-term name of LocalDateTime ? (continued)_"

Extra data point for completeness — that's no longer true as of Python 3.9: https://www.python.org/dev/peps/pep-0615/

@gilmoreorless - thanks! I updated the table.

I am definitely on @pipobscure's side here. I get the brevity argument, and it is important, but IMO it's not _as_ important as being consistent.

AFAIK there's universal agreement on this point. The only question in the meeting was which consistency is more important? Consistency between the two date/time types, or consistency between the unzoned date/time type, the date type, and the time type. In other words, if I have a date and want to add a time to it, should the names encourage me to convert it to a zoneless date/time, a zoned date/time, or should neither be preferred by the names?

The consensus was that consistency between the unzoned date/time type and date and time types was more important.

I disagreed (I expect most users to view the two date/time types as closer to each other than to Date or Time, and that naming should never encourage use of the zoneless type) but also didn't think this was worth blocking consensus.

The only consensus-blocking opinion I have is that the zoneless name should NOT be DateTime, because it'd encourage novices to choose the unzoned date/time type because in almost every other platform the word "DateTime" refers to the date/time type that's preferred for novices to try first. It's probably not an accident that in almost all platforms with an IANA zoned type, the word "DateTime" either refers to the zoned type or is not used at all.

Thanks for adding the notes, @ryzokuken!

AFAIK there's universal agreement on this point. The only question in the meeting was _which_ consistency is more important? Consistency between the two date/time types, or consistency between the unzoned date/time type, the date type, and the time type. In other words, if I have a date and want to add a time to it, should the names encourage me to convert it to a zoneless date/time, a zoned date/time, or should neither be preferred by the names?

The consensus was that consistency between the unzoned date/time type and date and time types was more important.

I agree with this. Looking more abstractly, if there are two classes ThingA and ThingB, and you can add them together into a combined class, I would definitely expect the combined class to follow the same naming pattern (such as ThingAB).

I would be wary of using ZonedDateTime to mean a date time with a zone.

'zone' as a verb has two common meanings, either 'to split into different
areas', as in
'the park has been zoned into four distinct bioregions, each with its own
ecological identity', or 'designate (a specific area) for use or
development as a particular zone in planning' as in 'the land is zoned for
housing'.

The date time in question has not been 'zoned'. It has a timezone.

On Mon, 5 Oct 2020, 12:31 Gilmore Davidson, notifications@github.com
wrote:

Thanks for adding the notes, @ryzokuken https://github.com/ryzokuken!

AFAIK there's universal agreement on this point. The only question in the
meeting was which consistency is more important? Consistency between
the two date/time types, or consistency between the unzoned date/time type,
the date type, and the time type. In other words, if I have a date and want
to add a time to it, should the names encourage me to convert it to a
zoneless date/time, a zoned date/time, or should neither be preferred by
the names?

The consensus was that consistency between the unzoned date/time type and
date and time types was more important.

I agree with this. Looking more abstractly, if there are two classes
ThingA and ThingB, and you can add them together into a combined class, I
would definitely expect the combined class to follow the same naming
pattern (such as ThingAB).

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/tc39/proposal-temporal/issues/707#issuecomment-703572971,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AGFWOVJO2Z5LM3IKD4QCLMLSJGVBJANCNFSM4OI7RDCA
.

@dvberzon

'zone' as a verb has two common meanings, either 'to split into different
areas', as in
'the park has been zoned into four distinct bioregions, each with its own
ecological identity', or 'designate (a specific area) for use or
development as a particular zone in planning' as in 'the land is zoned for
housing'.

While this is the correct meaning of the word "zoned" in the context of urban planning, this definition does not (and cannot possibly) apply to dates and times in JavaScript. In the case of JavaScript, zoned would instead have a different connotation, likely one linked to https://github.com/domenic/zones.

In the case of Temporal, however, the definition "containing a timezone" is more accurate than either of these.

And aside from that: a TimeZone IS an area of the world split of from the
whole. Whence the passive voice ā€œzonedā€. Interestingly enough this is so
similar with parks and housing, which might be why they are called
timezones. Additionally similarly to how development areas are called
ā€œzonedā€ and parks are ā€œzonedā€ the time of the world is also ā€œzonedā€.

On Mon, 5 Oct 2020 at 16:14, Ujjwal Sharma notifications@github.com wrote:

>
>

@dvberzon https://github.com/dvberzon

'zone' as a verb has two common meanings, either 'to split into different

areas', as in

'the park has been zoned into four distinct bioregions, each with its own

ecological identity', or 'designate (a specific area) for use or

development as a particular zone in planning' as in 'the land is zoned for

housing'.

While this is the correct meaning of the word "zoned" in the context of
urban planning, this definition does not (and cannot possibly) apply to
dates and times in JavaScript. In the case of JavaScript, zoned would
instead have a different connotation, likely one linked to
https://github.com/domenic/zones.

In the case of Temporal, however, the definition "containing a timezone"
is more accurate than either of these.

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/tc39/proposal-temporal/issues/707#issuecomment-703698108,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AADM5L3532IPFENZUQH3FP3SJHPELANCNFSM4OI7RDCA
.

Meeting 2020-10-08: Choices to poll are Plain, Civil, and Floating, and "Other (please reply)".

There are a few examples in English of taking a noun and turning it into a verb participle to indicate possession.

For example a person with money can (a bit archaically) be called ā€œA moneyed personā€

But you almost never do that in English with a noun that is already a verb.

For example you wouldn’t call a "result that included information about a doctor" a ā€œdoctored resultā€. People would immediately think that meant a result that had been tampered with.

Or a house that has a drive a ā€œDriven houseā€. That’s just nonsense.

As a native English speaker I would find it hard to imagine describing something as Zoned to mean something that possessed a zone.

I’m much more likely to go with the more common interpretation of either being split into zones or having been designated a zone.

I’m just pointing this out because ZonedDateTime does not to my ears sound like a description of a date time that includes a time zone.

On 5 Oct 2020, at 16:14, Ujjwal Sharma notifications@github.com wrote:

@dvberzon https://github.com/dvberzon
'zone' as a verb has two common meanings, either 'to split into different
areas', as in
'the park has been zoned into four distinct bioregions, each with its own
ecological identity', or 'designate (a specific area) for use or
development as a particular zone in planning' as in 'the land is zoned for
housing'.

While this is the correct meaning of the word "zoned" in the context of urban planning, this definition does not (and cannot possibly) apply to dates and times in JavaScript. In the case of JavaScript, zoned would instead have a different connotation, likely one linked to https://github.com/domenic/zones https://github.com/domenic/zones.

In the case of Temporal, however, the definition "containing a timezone" is more accurate than either of these.

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub https://github.com/tc39/proposal-temporal/issues/707#issuecomment-703698108, or unsubscribe https://github.com/notifications/unsubscribe-auth/AGFWOVMPQTVYL323EQRWX63SJHPENANCNFSM4OI7RDCA.

Thanks, because that’s exactly what this describes: a DateTime ā€œhaving been
designated a zoneā€

On Thu, 8 Oct 2020 at 17:41, Daniel van Berzon notifications@github.com
wrote:

There are a few examples in English of taking a noun and turning it into a
verb participle to indicate possession.

For example a person with money can (a bit archaically) be called ā€œA
moneyed personā€

But you almost never do that in English with a noun that is already a verb.

For example you wouldn’t call a "result that included information about a
doctor" a ā€œdoctored resultā€. People would immediately think that meant a
result that had been tampered with.

Or a house that has a drive a ā€œDriven houseā€. That’s just nonsense.

As a native English speaker I would find it hard to imagine describing
something as Zoned to mean something that possessed a zone.

I’m much more likely to go with the more common interpretation of either
being split into zones or having been designated a zone.

I’m just pointing this out because ZonedDateTime does not to my ears sound
like a description of a date time that includes a time zone.

On 5 Oct 2020, at 16:14, Ujjwal Sharma notifications@github.com wrote:

@dvberzon https://github.com/dvberzon
'zone' as a verb has two common meanings, either 'to split into different
areas', as in
'the park has been zoned into four distinct bioregions, each with its own
ecological identity', or 'designate (a specific area) for use or
development as a particular zone in planning' as in 'the land is zoned
for
housing'.

While this is the correct meaning of the word "zoned" in the context of
urban planning, this definition does not (and cannot possibly) apply to
dates and times in JavaScript. In the case of JavaScript, zoned would
instead have a different connotation, likely one linked to
https://github.com/domenic/zones https://github.com/domenic/zones.

In the case of Temporal, however, the definition "containing a timezone"
is more accurate than either of these.

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub <
https://github.com/tc39/proposal-temporal/issues/707#issuecomment-703698108>,
or unsubscribe <
https://github.com/notifications/unsubscribe-auth/AGFWOVMPQTVYL323EQRWX63SJHPENANCNFSM4OI7RDCA
.

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/tc39/proposal-temporal/issues/707#issuecomment-705690478,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AADM5L7V36KMJ3RMSJSAAP3SJXTULANCNFSM4OI7RDCA
.

FYI: while browsing the iCalendar spec (https://tools.ietf.org/html/rfc5545#section-3.3.5) for another reason, I noticed that it uses the adjective "floating" to describe unzoned date/time values:

FORM #1: DATE WITH LOCAL TIME

  The date with local time form is simply a DATE-TIME value that
  does not contain the UTC designator nor does it reference a time
  zone.  For example, the following represents January 18, 1998, at
  11 PM:

   19980118T230000

  DATE-TIME values of this type are said to be "floating" and are
  not bound to any time zone in particular.  They are used to
  represent the same hour, minute, and second value regardless of
  which time zone is currently being observed.

Twitter poll results after almost 2 days:

image

Meeting 2020-20-15: "Plain" wins! Also we'll use that same prefix on MonthDay and YearMonth too for consistency.

Final names are: ZonedDateTime, PlainDate, PlainTime, PlainDateTime, PlainYearMonth, PlainMonthDay

EDIT: conversion methods will also be renamed, e.g. toDate => toPlainDate.

What did we decide for the conversion methods within the Plain space?

  1. Temporal.PlainDateTime.prototype.toDate()
  2. Temporal.PlainDateTime.prototype.toPlainDate()

Hmm, we didn't talk about that, but I think it'd be Temporal.PlainDateTime.prototype.toPlainDate(). Otherwise it'd seem like the conversion should produce a legacy Date.

I'm confused, why is a twitter poll being used as the deciding factor?

It's just one factor. All three names polled were ones we thought might work. A non-representative (albeit more representative than Champions+Reviewers+GH-Commenters who are much more sophisticated than the median JS developer) sample of 166 developers preferred "Plain" over the alternatives by a wide margin. This isn't decisive but was a helpful signal that "Plain" would be a widely-acceptable prefix. Looking through the "Other" suggestions on Twitter didn't bring up any other names we thought might be more accepted. Therefore, in today's meeting we were able to get to consensus that "Plain" would be the best choice.

79 preferred Plain, 30 preferred Floating, 30 preferred Civil. The trend certainly implies this spread, but that's a pretty small sample size and difference. It'd be nice, prior to the relevant plenary, to gather more input about the name (including, ideally, the ability for folks to suggest things).

We’ve been through several iterations of this discussion. We’ve changed this a number of times. We’ve also asked the committee for input on a few occasions.

This decision wasn’t left to a poll, but rather we used a poll as the final piece of input to come to a conclusion.

So I’m strictly against revisiting this again. The time for this has passed. We’ll go to the committee and ask for agreement of course. And the committee will then have to come to consensus. If someone wants to withhold consensus due to the name of these classes, then so be it. But until then, revisiting this is not productive.

I don't believe I asked for anything to be revisited - I asked for more data to be gathered to present to plenary at the appropriate time.

Do you have a proposal for how to gather that data?

The trend certainly implies this spread, but that's a pretty small sample size and difference.

There are 11.7 million active JavaScript developers. In our poll, we captured 166 of them. The margin of error of this sample is 8% with 95% confidence. Therefore, Plain has a statistically significant lead.

@sffc i believe that presumes that the polled population (twitter users who happened to see the poll) does not vary significantly from the larger group of JS developers.

@pipobscure I'm not sure. perhaps a poll that lasts longer than a day or two would help obtain more results, especially if it were posted on multiple venues besides Twitter (not sure if this one was, or not).

The _trend_ certainly implies this spread, but that's a pretty small sample size and difference.

Statistically, 166 is more than enough for a nearly-3:1 spread to be significant. The sampling method (who's answering) probably introduces far more error than the sample size.

That said, what we've observed from running 3 different naming polls so far is that results don't change much after the first few dozen responses. This was surprising to me. I'd have expected, for example, that developers in North America (who probably saw the poll first) would vote differently from developers in Europe or Asia as they woke up and saw Twitter. Or that initial respondents would more likely to be TC39 or Temporal insiders who'd vote differently from later respondents who were random Twitter followers.

But what we ended up seeing across three polls that results are surprisingly consistent. Here's what this poll returned after only 18 votes. Numbers are within 8% of final results.

image

Here's what the previous poll was after 40 votes. All choices were within 8% of their final result.
image

This consistency in geography and insider/outsider has made me more confident than I expected to be that these unscientific Twitter polls are a reasonable approximation of the actual JS developer population. This is nice because launching these polls is so much easier than any other means I've ever used to sample 100s of developers.

FWIW, for a few years in the '00s I ran rolling surveys of 100s of developers per month from a population of 5M+ visitors to MSDN.com. Fielding, reducing errors in, and making sense of developer surveys is a topic I know fairly well from those years. Getting 150+ reasonably-representative responses in 24-48 hours, for free, is an amazing step forward compared to what we had back in the day. My past self is jealous!

The new name is decided and #700 has been updated with the new name, so I'm going to close this issue. Thanks everyone for your help picking "ZonedDateTime" as the name of this type!

I'd like to keep this open, the other types still need to be renamed to "Plain", so this is a good issue for anyone to pick up without lots of prior knowledge of Temporal.

OK sounds good.

Although, actually: would you be OK if I closed this one and opened up a new issue specifically for the PlainXxx rename? There's no need for someone to read through hundreds of bikeshed comments to pick up that work. ;-)

Sure, that works too.

To summarize this issue before closing it, here's the final names that were decided:

LocalDateTime => ZonedDateTime
Date => PlainDate
Time => PlainTime
DateTime => PlainDateTime
YearMonth => PlainYearMonth
MonthDay => PlainMonthDay

1072 will track the work to rename the unzoned types.

Was this page helpful?
0 / 5 - 0 ratings