Skip to content

Commit

Permalink
Normative: Remove support for nested time zone property bags
Browse files Browse the repository at this point in the history
Previously, "nested" time zone property bags were unwrapped up to one
level. That is, this object:
{
  timeZone: {
     // ...Temporal.TimeZone methods
  }
}
would not be considered to implement the TimeZone protocol, but would have
its timeZone property used instead, if it were passed to an API that
required a TimeZone protocol object.

These nested property bags are no longer supported. Discussion:
tc39#2104 (comment)

See: tc39#2104
  • Loading branch information
ptomato committed Apr 10, 2023
1 parent d26cf05 commit 1b09799
Show file tree
Hide file tree
Showing 4 changed files with 4 additions and 20 deletions.
1 change: 0 additions & 1 deletion docs/timezone.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ The object must have at least `getOffsetNanosecondsFor()` and `getPossibleInstan
Any object with those three methods will return the correct output from any Temporal property or method.
However, most other code will assume that custom time zones act like built-in `Temporal.TimeZone` objects.
To interoperate with libraries or other code that you didn't write, then you should implement all the other `Temporal.TimeZone` members as well: `toString()`, `toJSON()`, `getOffsetStringFor()`, `getPlainDateTimeFor()`, `getInstantFor()`, `getNextTransition()`, `getPreviousTransition()`, and `toJSON()`.
Your object must not have a `timeZone` property, so that it can be distinguished in `Temporal.TimeZone.from()` from other Temporal objects that have a time zone.

The identifier of a custom time zone must consist of one or more components separated by slashes (`/`), as described in the [tzdata documentation](https://htmlpreview.github.io/?https://github.com/eggert/tz/blob/master/theory.html#naming).
Each component must consist of between one and 14 characters.
Expand Down
5 changes: 2 additions & 3 deletions polyfill/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1091,7 +1091,6 @@ export namespace Temporal {
*/
export interface TimeZoneProtocol {
id: string;
timeZone?: never;
getOffsetNanosecondsFor(instant: Temporal.Instant | string): number;
getOffsetStringFor?(instant: Temporal.Instant | string): string;
getPlainDateTimeFor?(instant: Temporal.Instant | string, calendar?: CalendarLike): Temporal.PlainDateTime;
Expand All @@ -1106,7 +1105,7 @@ export namespace Temporal {
toJSON?(): string;
}

export type TimeZoneLike = TimeZoneProtocol | string | { timeZone: TimeZoneProtocol | string };
export type TimeZoneLike = TimeZoneProtocol | string;

/**
* A `Temporal.TimeZone` is a representation of a time zone: either an
Expand All @@ -1121,7 +1120,7 @@ export namespace Temporal {
*
* See https://tc39.es/proposal-temporal/docs/timezone.html for more details.
*/
export class TimeZone implements Omit<Required<TimeZoneProtocol>, 'timeZone'> {
export class TimeZone implements TimeZoneProtocol {
static from(timeZone: TimeZoneLike): Temporal.TimeZone | TimeZoneProtocol;
constructor(timeZoneIdentifier: string);
readonly id: string;
Expand Down
10 changes: 1 addition & 9 deletions polyfill/lib/ecmascript.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -1969,19 +1969,11 @@ export const ES = ObjectAssign({}, ES2022, {

ToTemporalTimeZoneSlotValue: (temporalTimeZoneLike) => {
if (ES.Type(temporalTimeZoneLike) === 'Object') {
if (ES.IsTemporalTimeZone(temporalTimeZoneLike)) return temporalTimeZoneLike;
if (ES.IsTemporalZonedDateTime(temporalTimeZoneLike)) return GetSlot(temporalTimeZoneLike, TIME_ZONE);
if (ES.IsTemporalCalendar(temporalTimeZoneLike)) {
throw new RangeError('Expected a time zone object but received a Temporal.Calendar');
}
if (!('timeZone' in temporalTimeZoneLike)) return temporalTimeZoneLike;
temporalTimeZoneLike = temporalTimeZoneLike.timeZone;
if (ES.Type(temporalTimeZoneLike) === 'Object') {
if (ES.IsTemporalCalendar(temporalTimeZoneLike)) {
throw new RangeError('Expected a time zone object as the timeZone property but received a Temporal.Calendar');
}
if (!('timeZone' in temporalTimeZoneLike)) return temporalTimeZoneLike;
}
return temporalTimeZoneLike;
}
const identifier = ES.ToString(temporalTimeZoneLike);
return ES.ParseTemporalTimeZone(identifier);
Expand Down
8 changes: 1 addition & 7 deletions spec/timezone.html
Original file line number Diff line number Diff line change
Expand Up @@ -558,16 +558,10 @@ <h1>
</dl>
<emu-alg>
1. If Type(_temporalTimeZoneLike_) is Object, then
1. If _temporalTimeZoneLike_ has an [[InitializedTemporalTimeZone]] internal slot, then
1. Return _temporalTimeZoneLike_.
1. If _temporalTimeZoneLike_ has an [[InitializedTemporalZonedDateTime]] internal slot, then
1. Return _temporalTimeZoneLike_.[[TimeZone]].
1. If _temporalTimeZoneLike_ has an [[InitializedTemporalCalendar]] internal slot, throw a *RangeError* exception.
1. If ? HasProperty(_temporalTimeZoneLike_, *"timeZone"*) is *false*, return _temporalTimeZoneLike_.
1. Set _temporalTimeZoneLike_ to ? Get(_temporalTimeZoneLike_, *"timeZone"*).
1. If Type(_temporalTimeZoneLike_) is Object, then
1. If _temporalTimeZoneLike_ has an [[InitializedTemporalCalendar]] internal slot, throw a *RangeError* exception.
1. If ? HasProperty(_temporalTimeZoneLike_, *"timeZone"*) is *false*, return _temporalTimeZoneLike_.
1. Return _temporalTimeZoneLike_.
1. Let _identifier_ be ? ToString(_temporalTimeZoneLike_).
1. Let _parseResult_ be ? ParseTemporalTimeZoneString(_identifier_).
1. If _parseResult_.[[Name]] is not *undefined*, then
Expand Down

0 comments on commit 1b09799

Please sign in to comment.