tc39 / proposal-temporal

Provides standard objects and functions for working with dates and times.
https://tc39.es/proposal-temporal/docs/
Other
3.34k stars 153 forks source link

What should be the long-term name of `LocalDateTime` ? #707

Closed justingrant closed 4 years ago

justingrant commented 4 years ago

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.

justingrant commented 4 years ago

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!

gilmoreorless commented 4 years ago

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:

pipobscure commented 4 years ago

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

justingrant commented 4 years ago

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. ;-)

ptomato commented 4 years ago

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.

justingrant commented 4 years ago

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.

pipobscure commented 4 years ago

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.

pipobscure commented 4 years ago

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 šŸ˜€

ptomato commented 4 years ago

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:

sffc commented 4 years ago

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.

justingrant commented 4 years ago

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.

ptomato commented 4 years ago

:-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.

pipobscure commented 4 years ago

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?

sffc commented 4 years ago

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.

ljharb commented 4 years ago

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

ptomato commented 4 years ago

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.

pipobscure commented 4 years ago

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

pipobscure commented 4 years ago

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?

justingrant commented 4 years ago

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:

Why?

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

sffc commented 4 years ago

@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).

sffc commented 4 years ago

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 commented 4 years ago

@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:

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

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).

sffc commented 4 years ago

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).

justingrant commented 4 years ago

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:

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.

sffc commented 4 years ago

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.

pipobscure commented 4 years ago

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:

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.

sffc commented 4 years ago

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

justingrant commented 4 years ago

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.

bathos commented 4 years ago

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?

tiagobnobrega commented 4 years ago

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

pipobscure commented 4 years ago

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)
stebogit commented 4 years ago

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.

pipobscure commented 4 years ago

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.

stebogit commented 4 years ago

@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

pipobscure commented 4 years ago

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.

kaizhu256 commented 4 years ago

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.

justingrant commented 4 years ago

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.

stebogit commented 4 years ago

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?

pipobscure commented 4 years ago

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:

justingrant commented 4 years ago

So it is the very opposite of an Instant.

@pipobscure you mean opposite of a DateTime, right?

pipobscure commented 4 years ago

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

ljharb commented 4 years ago

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

tiagobnobrega commented 4 years ago

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.

tiagobnobrega commented 4 years ago

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.

ptomato commented 4 years ago

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)).

pipobscure commented 4 years ago

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.

sffc commented 4 years ago

-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.

ptomato commented 4 years ago

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.

pipobscure commented 4 years ago

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.

pipobscure commented 4 years ago

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.