Closed justingrant closed 4 years ago
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.
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.
So here's my conclusions based on this data:
IMHO we should do one more round of polling to inform our answer to these two questions:
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 justDateTime
) andFloatingDateTime
? 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:
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 doesDate
andTime
.
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.
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.
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.
Should Date, Time, YearMonth, MonthDay get prefixes too?
What to call the unzoned type?
What to call the zoned type
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:
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 .
In #700, @InExtremaRes asked:
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.