-
Notifications
You must be signed in to change notification settings - Fork 159
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Clarify which time zones must be supported in a non-402 implementation #1305
Conversation
Codecov Report
@@ Coverage Diff @@
## main #1305 +/- ##
=======================================
Coverage 94.94% 94.94%
=======================================
Files 19 19
Lines 9682 9682
Branches 1519 1519
=======================================
Hits 9193 9193
Misses 481 481
Partials 8 8
Flags with carried forward coverage won't be shown. Click here to find out more. Continue to review full report at Codecov.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall the approach LGTM, but it seems like it might be missing some kind of glue to tie everything together - perhaps a host hook that returns the available list of time zone names, which is stored on the realm and does not change throughout the realm's lifetime, and then these operations can consult that list?
See also Note 2 under https://tc39.es/proposal-temporal/#sec-temporal-tolocaltime — we wrote it that way to encourage implementations to keep the existing tzdata constant throughout the lifetime of the process, in the case of updates, but still allow flexibility for memory-constrained implementations to only keep the tzdata in memory for time zones that had already been accessed. Having a host hook return the list of valid time zone names wouldn't be compatible with that, since that information might change if the tzdata is updated in the meantime. But I'll try to figure something out. |
@ptomato true - it'd be compatible as long as the host hook was repeatedly called, and not called once and cached. |
@ljharb : It seems https://tc39.es/proposal-intl-enumeration/#sec-intl.supportedvaluesof covers the use cases already. From trying to understand what a host hook is (sorry, a bit new to this still), it sounds like implementing that as a host hook is appropriate because it is not technically implementation defined. Are there other benefits to using a host hook, or additional costs to the external calls?
Does a host hook imply or provide the consistency in the 'note 2' link @ptomato shared above [1]? From my quite limited understanding it seems repeatedly calling the host hook would create exactly the problem described, wherein changed tzdata could appear through the API in the same object lifecycle. I would propose implementing proposal-intl-enumeration's supportedValuesOf as a host hook, and only noting consistency recommendations in Temporal. I propose that implementations only be required to support UTC. [1]
|
@cjtenny since Intl is not required, nothing in intl supports the use cases I’m asking about, which is 262 absent 402 (I’m not talking about exposing the lists to users, I’m talking about making the 262 spec text more coherent). You’re right that my previous concern (that it would be bad if hosts changed what’s supported mid-flight) directly conflicts with @ptomato’s stated goal of allowing exactly that, but to me that seems only the difference between whether the host hook is called once, or every time (assuming a host hook is the best way to improve the spec text here). |
That's exactly what I don't know 😄 I guess I don't really understand at this point what the important difference is here between a host hook and an implementation-defined operation. Can you clarify a bit more what you think it would provide? |
Host hooks are explicit - when they’re called, what arguments they have available, and what constraints apply to the return type are all mandated and specified. “implementation-defined” can mean virtually anything. |
I'm still trying to figure out what the appropriate host hook would be. I don't think it's a list of all supported time zone names, because that doesn't allow for the canonicalization in CanonicalizeTimeZone of, e.g., |
6379e58
to
9e3dbea
Compare
I think @ptomato's goal isn't allowing exactly that; it's just a different scale of mid-flight. Temporal objects must remain consistent, and the reasonable lifetime for that consistency is what's not yet defined; I think we can probably all agree on the lower bound of the individual lifetime of an object encapsulating a timeZone, and the upper bound of the lifetime of the entire execution environment (realm?). I'd support
Edit: I think I agree with @ptomato's update that DefaultTimeZone doesn't need to be a host hook, just needs to return a host-defined value. |
9e3dbea
to
e0aed78
Compare
OK, please take a look if these host hooks seem reasonable. |
spec/timezone.html
Outdated
<li>It must always return either *true* or *false*.</li> | ||
</ul> | ||
<p> | ||
The implementation of HostIsValidTimeZoneName should return *true* if _timeZone_, converted to upper case, is equal to one of the built-in time zone names, converted to upper case. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should perhaps https://tc39.es/ecma262/#sec-timezoneestring be modified so that any timezone Date is capable of producing, Temporal can recognize?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you mean that the output of Date()
should change from e.g. 'Fri Jan 22 2021 11:07:52 GMT-0800 (Pacific Standard Time)'
to 'Fri Jan 22 2021 11:07:52 -08:00[America/Vancouver]'
? That doesn't seem like it would be web compatible.
That does remind me that HostIsValidTimeZoneName should always recognize all offset-only time zone strings, though. I'll make sure that's added. Actually no, that goes through a different code path already.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, that's not what i mean. I mean that if an implementation lacks 402 and supports "America/Vancouver" somehow via Date, it would be nice if it was compelled to also do so for Temporal.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure I understand what you mean by supporting a time zone via Date, then. You can get a Date in UTC or in the local time zone, but internally it's the same thing as a Temporal.Instant, it doesn't have a time zone. Time zones aren't parsed by Date.parse()
as far as I can tell. TimeZoneString is only used for output purposes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's the "local time zone" part i'm interested in. I would prefer it to not be possible that a compliant engine exists where Temporal has fewer timezones than Date (ie, i want every possible timezone new Date()
can represent to be representable in Temporal, whether 402 is present or not).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure that's accurate; date.getTimezoneOffset()
returns the UTC offset of the host system's current time zone, at the time specified by date
. This is consistent with Date being a number of milliseconds since the Unix epoch and not having an inherent time zone. If Date held any other state besides a number of milliseconds, it would be apparent from looking at Date's internal slots in §21.4.5 Properties of Date Instances.
The toString
output is controlled by TimeZoneString as you linked above, and the output string is unfortunately not mentioned to be anything more than implementation-defined, but at least where I've tried it, the time zone name that's output is always the host's current time zone.
We cannot parse strings like "PST" into time zones because they are not mapped unambiguously to actual time zones. "CST", for example, stands for Central Standard Time, Cuba Standard Time (which is currently at the same offset as EST in the US), and China Standard Time. Date.parse()
does make an effort to parse those abbreviations, but in the implementation that I tried it in, it only understands the US ones (not, for example CET), and Date.parse()
is not a good thing to emulate anyway.
I think I understand what you are asking for now, but hopefully this clarifies that the extent of what's possible is to require that implementations must have the output of DefaultTimeZone as a builtin time zone.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry if i was unclear - I’m not saying the outputs must be observably linked, I’m saying that I’d like whatever conceptual local timezone Dates represent to always also be supported by Temporal.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. As far as I understand, this PR ensures that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you help me understand how? Without spec steps or normative prose dictating that as a requirement, it seems like an engine would be free to only support UTC on Temporal, but continue to have local timezones for Date.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure! 😄 Maybe I should have said "this PR ensures that to the extent that I believe it to be possible". Since Date does not have a time zone, we should examine the places where you can get information about the host's local time zone through Date. Those are, as you identified, date.getTimezoneOffset()
(where you can obtain the offset at the time given by the Date) and date.toString()
/date.toTimeString()
(where you can additionally obtain an unofficial name of the time zone.)
I believe the constraint is satisfied due to the language in DefaultTimeZone
The DefaultTimeZone abstract operation returns a String value representing the valid and canonicalized time zone name for the host environment's current time zone.
and the language in the first section
If the return value of DefaultTimeZone is different from "UTC", and does not satisfy the syntax of a TimeZoneNumericUTCOffset, then implementations must support that time zone as a built-in time zone as well.
So, if the host environment's current time zone is not UTC, and not a constant-offset time zone like "-08:00"
which some environments might want to provide in order to avoid leaking information about the host, then 262 must support it as a built-in time zone. I believe that this precludes implementations from having a local time zone for Date but not for Temporal.
The unofficial name of the local time zone in date.toString()
ultimately comes from step 8 of TimeZoneString which is an implementation-defined string in a form which is not (and cannot be) known to Temporal for reasons that I explained above. Changing this to use an official time zone name would not be web compatible.
The offset from date.getTimezoneOffset()
comes from t − LocalTime(t) which boils down to −LocalTZA(t, true) (and this is also where toString()
gets its offset.) As per the text of LocalTZA, it is
an implementation-defined algorithm that returns an integral Number representing the local time zone adjustment, or offset, in milliseconds. The local political rules for standard time and daylight saving time in effect at t should be used to determine the result in the way specified in this section.
We could maybe change this to something like "representing the adjustment, or offset, in milliseconds, of the host environment's current time zone" to make sure the same term is used, but I don't believe the current language leaves open the possibility that a host could choose to have one current time zone in LocalTZA and a different one in DefaultTimeZone.
Another additional restriction that we could add, would be that DefaultTimeZone must return a named or offset time zone for which the offset at all possible times t is equal to the return value of LocalTZA(t, true). That seems redundant to me, but if you're not convinced by the status quo, then maybe this change would be an improvement?
I hope this helps clear up any doubts. If you have concrete suggestions for tightening the language or if there are loopholes that I haven't noticed, please let me know; otherwise, I will consider this resolved.
e0aed78
to
6317092
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just one more substantive question, pretty small.
6317092
to
b7e7070
Compare
I think this should just be an abstract algorithm defined in 262 which is overridden by 402. I don't think it makes sense to use a host hook here, since the algorithms are defined in these specifications, not the host. For something to be a host hook, we would expect it to tie into some logic in other specifications (e.g., HTML) but I think we can define all of the standard here. In case not everyone here is very familiar with ECMA-402: implementation-defined algorithms are necessarily used widely in that context, to allow implementations to include their own data, so they are appropriate to use here. ECMA-402 does not tend to use host hooks to be more concrete and avoid implementation-defined algorithms, since it's important that different implementations of ECMA-402 on the Web (for example) have the freedom to use tailored locale data. |
The abstract operations dealing with the system time zone and the time zone names were part of 402, but here they need to move into 262, without obligating non-402 implementations to offer the full list of time zone names. Closes: #1292
b7e7070
to
9d834b2
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This makes sense to me.
The abstract operations dealing with the system time zone and the time
zone names were part of 402, but here they need to move into 262, without
obligating non-402 implementations to offer the full list of time zone
names.
Closes: #1292