As a Temporal noob, I wanted to share a challenge I've had when reading code that uses Temporal: it's often hard to know which Temporal type an object is. Is it Absolute? DateTime? Date? This comes up a lot because most non-trivial Temporal patterns involve one or more type conversions. This especially happens when there's a long chain of calls where there's no local variable names to provide context.
After running into this problem a few times, I realized what was confusing me most: the inTimeZone() method was named the same in both Absolute and DateTime. This means that if you see code like event.inTimeZone(tz) you know that one of them is a DateTime and the other is an Absolute. But you don't know which is which, so you have to scan forward or backward in the code until you find a clue about one of the types. Or if you're in an IDE, intellisense might help you. But I still found it distracting to have to think about this every time.
Also, it felt weird for the same method name to perform the opposite operation in two different classes. Like if .foo() meant "plus" in one type and "minus" in another.
I think it'd be clearer if those two methods had unique names that clarified what the destination type will be. toAbsolute/toDateTime? asAbsolute/asDateTime? getAbsolute/getDateTime?
This is a fairly minor issue, but I did want to record it in case other people testing the API have had a similar experience.
I guess this is something that could be considered in the champions meeting before freezing the API, thanks.
When I was looking through the cookbook examples there was something that felt slightly off but I couldn't quite place it. I think you've nailed what it was — in hindsight it should have been obvious to me.
On reflection, it's a bit weird to have two concepts of "a fixed point in time, without a time zone" and "an abstract local wall clock time, without a time zone", then convert between the two of them via a method called .inTimeZone(). (I totally understand _why_ it's called that, and the underlying model, but it still feels like unintuitive naming.)
I like the idea of dateTime.toAbsolute(timeZone) and absolute.toDateTime(timeZone). But if we went with that naming scheme, it would hinder a possible renaming of Absolute to Timestamp (https://github.com/tc39/proposal-temporal/issues/569#issuecomment-628822750). If I saw dateTime.toTimestamp(timeZone) I would assume I'd get a numeric value back, not a Temporal.Timestamp object (because a lot of programming languages already define "timestamp" as "an integer value of time since an epoch").
In the ZonedAbsolute data model I suggested in https://github.com/tc39/proposal-temporal/issues/569#issuecomment-631128833, the methods would be called withCalendar (ZonedAbsolute to DateTime) and inTimeZone (DateTime to ZonedAbsolute).
Here's a specific use-case I ran across today. In my app, I put all date-related logic into a single module of utility functions. Here's how one of these functions could be written using Temporal. Note that there's no context or surrounding code that I can use to infer types.
export function addHours(t, hours, tz) {
return t.inTimeZone(tz).plus({hours}).inTimeZone(tz)
}
A few problems here:
plus is incrementing clock time or real-world timeDate.Of course a real reusable library would have better variable/function names, JSDoc, etc. But I think it's reasonable for method names to help provide context for code in isolation.
Out of curiosity, what are the advantages of the current naming scheme? What use-cases are made easier by making the names identical for both operations?
Personally, I've also found the use of the same name surprising when writing Temporal code samples. I'd be in favor of using different method names (no particular opinion on what the method name is).
I haven't had a lot of trouble using inTimeZone myself, but just to float a proposal, what about toAbsolute and toDateTime as the method names?
@ryzokuken what about
toAbsoluteandtoDateTimeas the method names?
That's exactly what I expected these methods to be named.
I'd also have a slight preference for using the to* convention on the other conversion methods which add information:
We also have a few methods that remove information, which are named get*. We could rename these or keep them the same:
I would be happy with renaming every type conversion method to toFoo for consistency.
Common prefixes like @ryzokuken recommends are also usually good for IDE experience. With autocomplete, the developer could just type "to" (or "as" or "get" or whatever is decided) and then start typing the name of the desired type. Also, seeing the full list of conversion options in autocomplete will probably also help developers discover the presence of more obscure types like MonthDay.
I'm fairly attached to the withFoo methods, I find them very visually intuitive. In yearMonth.withDay(1), I can literally imagine the day being tacked on to the YearMonth to form a Date. :smile:
@ptomato, I originally agreed with you but after using Temporal for a while I came around to @ryzokuken's POV. After a few days of using Temporal whenever I needed to do a type conversion I always thought first about the type I wanted and only secondarily about the parameter types I needed to use to get it. I found it more natural to focus on ends over means. It's also why I find "inTimeZone" so frustrating-- because I'm not trying to get a TimeZone, I'm trying to get a DateTime or Absolute!
I also like the IDE experience where you just type "to" and the name of the desired type. No thinking required. Also I like the idea of using IDE autocomplete for "marketing" of less common Temporal types by putting them next to more popular neighbors like DateTime.
One exception might be withCalendar because it doesn't result in a new type. Although inCalendar might be shorter if all the other with* and in* methods are renamed.
Meeting, June 18: We'll rename everything to toTheTypeThatItConvertsTo. (inTimeZone → toAbsolute or toDateTime; withYear → toDate; getMonthDay → toMonthDay), and do this fairly quickly while still in the early stages of gathering feedback.
What about withCalendar? Unlike all other with*/in*/get* methods, withCalendar doesn't change the resulting type. Should it stay withCalendar? Switch to inCalendar?
Personally, I think withCalendar should stay, both because it doesn't change the resulting type, and it is similar to with({ calendar }).
Most helpful comment
I haven't had a lot of trouble using
inTimeZonemyself, but just to float a proposal, what abouttoAbsoluteandtoDateTimeas the method names?