Skip to content
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

Merged
merged 2 commits into from
Jan 27, 2021

Conversation

ptomato
Copy link
Collaborator

@ptomato ptomato commented Jan 19, 2021

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

@codecov
Copy link

codecov bot commented Jan 19, 2021

Codecov Report

Merging #1305 (54a7ab7) into main (ebd2df4) will not change coverage.
The diff coverage is n/a.

Impacted file tree graph

@@           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           
Flag Coverage Δ
test262 54.42% <ø> (ø)
tests 90.86% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.


Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update ebd2df4...c502fef. Read the comment docs.

Copy link
Member

@ljharb ljharb left a 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?

spec/timezone.html Outdated Show resolved Hide resolved
spec/timezone.html Outdated Show resolved Hide resolved
@ptomato
Copy link
Collaborator Author

ptomato commented Jan 20, 2021

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.

@ljharb
Copy link
Member

ljharb commented Jan 20, 2021

@ptomato true - it'd be compatible as long as the host hook was repeatedly called, and not called once and cached.

spec/timezone.html Outdated Show resolved Hide resolved
spec/timezone.html Outdated Show resolved Hide resolved
@cjtenny
Copy link
Collaborator

cjtenny commented Jan 21, 2021

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?

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

@ptomato true - it'd be compatible as long as the host hook was repeatedly called, and not called once and cached.

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]
Quoting the content of the note, since the fragment doesn't take you quite to the right point:

Time zone information is subject to change, and host environments may update their time zone information at any time. At a minimum, implementations must ensure that the time zone information for each particular value of timeZone individually remains constant starting from the time it is first accessed, for the lifetime of the surrounding agent. Furthermore, it is recommended that the time zone information for all values of timeZone as a whole remains the same for the lifetime of the surrounding agent.

@ljharb
Copy link
Member

ljharb commented Jan 21, 2021

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

@ptomato
Copy link
Collaborator Author

ptomato commented Jan 21, 2021

(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?

@ljharb
Copy link
Member

ljharb commented Jan 21, 2021

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.

@ptomato
Copy link
Collaborator Author

ptomato commented Jan 22, 2021

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., Asia/Calcutta to Asia/Kolkata, and I'm not sure why it would be okay for that to be implementation-defined but not the other things. Maybe all three of these operations would just be better off as host hooks?

@ptomato ptomato force-pushed the 1292-defaulttimezone-spec-text branch from 6379e58 to 9e3dbea Compare January 22, 2021 02:05
@cjtenny
Copy link
Collaborator

cjtenny commented Jan 22, 2021

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

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

  • Making all three of these host hooks
  • Only requiring UTC and the value of DefaultTimeZone to be supported; and
  • Specifying the frequency at which they are cached vs called

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.

spec/intl.html Outdated Show resolved Hide resolved
@ptomato ptomato force-pushed the 1292-defaulttimezone-spec-text branch from 9e3dbea to e0aed78 Compare January 22, 2021 06:31
@ptomato ptomato requested a review from cjtenny January 22, 2021 06:34
@ptomato
Copy link
Collaborator Author

ptomato commented Jan 22, 2021

OK, please take a look if these host hooks seem reasonable.

spec/intl.html Show resolved Hide resolved
<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.
Copy link
Member

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?

Copy link
Collaborator Author

@ptomato ptomato Jan 22, 2021

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.

Copy link
Member

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.

Copy link
Collaborator Author

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.

Copy link
Member

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

Copy link
Collaborator Author

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.

Copy link
Member

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.

Copy link
Collaborator Author

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.

Copy link
Member

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.

Copy link
Collaborator Author

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

spec/timezone.html Outdated Show resolved Hide resolved
@ptomato ptomato force-pushed the 1292-defaulttimezone-spec-text branch from e0aed78 to 6317092 Compare January 22, 2021 19:14
Copy link
Collaborator

@cjtenny cjtenny left a 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.

spec/timezone.html Outdated Show resolved Hide resolved
spec/timezone.html Outdated Show resolved Hide resolved
spec/intl.html Outdated Show resolved Hide resolved
@ptomato ptomato force-pushed the 1292-defaulttimezone-spec-text branch from 6317092 to b7e7070 Compare January 23, 2021 02:03
@littledan
Copy link
Member

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
@ptomato ptomato force-pushed the 1292-defaulttimezone-spec-text branch from b7e7070 to 9d834b2 Compare January 27, 2021 06:38
@ptomato ptomato requested a review from littledan January 27, 2021 06:39
Copy link
Collaborator

@Ms2ger Ms2ger left a 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.

spec/timezone.html Outdated Show resolved Hide resolved
spec/timezone.html Outdated Show resolved Hide resolved
spec/timezone.html Outdated Show resolved Hide resolved
spec/timezone.html Outdated Show resolved Hide resolved
@Ms2ger Ms2ger merged commit bb849bb into main Jan 27, 2021
@Ms2ger Ms2ger deleted the 1292-defaulttimezone-spec-text branch January 27, 2021 10:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

editor review: 402 independence
5 participants