diff --git a/docs/timezone.md b/docs/timezone.md index f0c02f0fa3..0ad41478a3 100644 --- a/docs/timezone.md +++ b/docs/timezone.md @@ -219,74 +219,6 @@ When overriding `id`, `toString()` and `toJSON()` should also be overridden. ## Methods -### timeZone.**equals**(_other_: Temporal.TimeZone | object | string) : boolean - -**Parameters:** - -- `other` (`Temporal.TimeZone` object, object implementing the `Temporal.TimeZone` protocol, or a string time zone identifier): Another time zone to compare. - -**Returns:** `true` if `timeZone` and `other` are equivalent, or `false` if not. - -Compares two time zones for equivalence. -Equality is determined by the following algorithm: - -- If `timeZone === other`, then the time zones are equivalent. -- Otherwise, `timeZone.id` is compared to `other` (or `other.id` if `other` is an object). - If any of the following conditions are true, then the time zones are equivalent: - - Both string identifiers are Zone or Link names in the [IANA Time Zone Database](https://www.iana.org/time-zones), and they resolve to the same Zone name. - This resolution is case-insensitive. - - Both string identifiers are custom time zone identifiers that are equal according to `===`. - This comparison is case-sensitive and does not normalize different Unicode characters. - - Both identifiers are numeric offset time zone identifiers like "+05:30", and they represent the same offset. -- Otherwise, the time zones are not equivalent. - -Note that "resolve to the same Zone name" noted above is behavior that can vary between ECMAScript and other consumers of the IANA Time Zone Database. -ECMAScript implementations generally do not allow identifiers to be equivalent if they represent different ISO 3166-1 Alpha-2 country codes. -However, non-ECMAScript platforms may merge Zone names across country boundaries. -See [above](#variation-between-ecmascript-and-other-consumers-of-the-iana-time-zone-database) to learn more about this variation. - -Time zones that resolve to different Zones in the IANA Time Zone Database are not equivalent, even if those Zones always use the same offsets. -Offset time zones and IANA time zones are also never equivalent. - -Example usage: - - -```javascript -kolkata = Temporal.TimeZone.from('Asia/Kolkata'); -kolkata.id; // => "Asia/Kolkata" -calcutta = Temporal.TimeZone.from('Asia/Calcutta'); -calcutta.id; // => "Asia/Calcutta" -kolkata.equals(calcutta); // => true -kolkata.equals('Asia/Calcutta'); // => true -kolkata.equals('Asia/Colombo'); // => false - -// IANA Time Zone Database identifiers are case insensitive -kolkata.equals('asia/calcutta'); // => true - -// Offset time zones are never equivalent to named time zones -kolkata.equals('+05:30'); // => false -zeroOffset = Temporal.TimeZone.from('+00:00'); -zeroOffset.equals('UTC'); // false - -// For offset time zones, any valid format is accepted -zeroOffset.equals('+00:00'); // => true -zeroOffset.equals('+0000'); // => true -zeroOffset.equals('+00'); // => true - -// Custom time zone identifiers are compared case-sensitively -class Custom1 extends Temporal.TimeZone { - constructor() { super('UTC'); } - get id() { return 'Moon/Cheese'; } -} -class Custom2 extends Temporal.TimeZone { - constructor() { super('UTC'); } - get id() { return 'Moon/CHEESE'; } -} -new Custom1().equals(new Custom1()); // => true -new Custom1().equals(new Custom2()); // => false -``` - - ### timeZone.**getOffsetNanosecondsFor**(_instant_: Temporal.Instant | string) : number **Parameters:** diff --git a/docs/zoneddatetime.md b/docs/zoneddatetime.md index 2c3277b78b..1b3f184f70 100644 --- a/docs/zoneddatetime.md +++ b/docs/zoneddatetime.md @@ -1223,6 +1223,30 @@ To ignore both time zones and calendars, compare the instants of both: zdt.toInstant().equals(other.toInstant()); ``` +To compare time zone IDs directly, compare two ZonedDateTimes with the same instant and calendar: + +```javascript +zdt.withTimeZone(id1).equals(zdt.withTimeZone(id2)); +``` + +The time zones of _zonedDateTime_ and _other_ are considered equivalent by the following algorithm: + +- If the time zone objects are the same object, then the time zones are equivalent. +- Otherwise, the IDs are compared. + If any of the following conditions are true, then the time zones are equivalent: + - Both string identifiers are Zone or Link names in the [IANA Time Zone Database](https://www.iana.org/time-zones), and they resolve to the same Zone name. + This resolution is case-insensitive. + - Both identifiers are numeric offset time zone identifiers like "+05:30", and they represent the same offset. +- Otherwise, the time zones are not equivalent. + +Note that "resolve to the same Zone name" noted above is behavior that can vary between ECMAScript and other consumers of the IANA Time Zone Database. +ECMAScript implementations generally do not allow identifiers to be equivalent if they represent different ISO 3166-1 Alpha-2 country codes. +However, non-ECMAScript platforms may merge Zone names across country boundaries. +See [above](#variation-between-ecmascript-and-other-consumers-of-the-iana-time-zone-database) to learn more about this variation. + +Time zones that resolve to different Zones in the IANA Time Zone Database are not equivalent, even if those Zones always use the same offsets. +Offset time zones and IANA time zones are also never equivalent. + Example usage: ```javascript @@ -1230,6 +1254,21 @@ zdt1 = Temporal.ZonedDateTime.from('1995-12-07T03:24:30.000003500+01:00[Europe/P zdt2 = Temporal.ZonedDateTime.from('1995-12-07T03:24:30.000003500+01:00[Europe/Brussels]'); zdt1.equals(zdt2); // => false (same offset but different time zones) zdt1.equals(zdt1); // => true + +// To compare time zone IDs, use withTimeZone() with each ID on the same +// ZonedDateTime instance, and use equals() to compare +kolkata = zdt1.withTimeZone('Asia/Kolkata'); +kolkata.equals(zdt.withTimeZone('Asia/Calcutta')); // => true + +// Offset time zones are never equivalent to named time zones +kolkata.equals(zdt.withTimeZone('+05:30')); // => false +zeroOffset = zdt1.withTimeZone('+00:00'); +zeroOffset.equals(zdt1.withTimeZone('UTC')); // => false + +// For offset time zones, any valid format is accepted +zeroOffset.equals(zdt1.withTimeZone('+00:00')); // => true +zeroOffset.equals(zdt1.withTimeZone('+0000')); // => true +zeroOffset.equals(zdt1.withTimeZone('+00')); // => true ``` ### zonedDateTime.**toString**(_options_?: object) : string diff --git a/polyfill/index.d.ts b/polyfill/index.d.ts index a30a932528..7492198b95 100644 --- a/polyfill/index.d.ts +++ b/polyfill/index.d.ts @@ -1124,7 +1124,6 @@ export namespace Temporal { static from(timeZone: TimeZoneLike): Temporal.TimeZone | TimeZoneProtocol; constructor(timeZoneIdentifier: string); readonly id: string; - equals(timeZone: TimeZoneLike): boolean; getOffsetNanosecondsFor(instant: Temporal.Instant | string): number; getOffsetStringFor(instant: Temporal.Instant | string): string; getPlainDateTimeFor(instant: Temporal.Instant | string, calendar?: CalendarLike): Temporal.PlainDateTime; diff --git a/polyfill/lib/timezone.mjs b/polyfill/lib/timezone.mjs index ca5b511716..9bfe832324 100644 --- a/polyfill/lib/timezone.mjs +++ b/polyfill/lib/timezone.mjs @@ -47,11 +47,6 @@ export class TimeZone { if (!ES.IsTemporalTimeZone(this)) throw new TypeError('invalid receiver'); return GetSlot(this, TIMEZONE_ID); } - equals(other) { - if (!ES.IsTemporalTimeZone(this)) throw new TypeError('invalid receiver'); - const timeZoneSlotValue = ES.ToTemporalTimeZoneSlotValue(other); - return ES.TimeZoneEquals(this, timeZoneSlotValue); - } getOffsetNanosecondsFor(instant) { if (!ES.IsTemporalTimeZone(this)) throw new TypeError('invalid receiver'); instant = ES.ToTemporalInstant(instant); diff --git a/spec/timezone.html b/spec/timezone.html index 96ddff163d..fa0ad251a9 100644 --- a/spec/timezone.html +++ b/spec/timezone.html @@ -106,19 +106,6 @@

get Temporal.TimeZone.prototype.id

- -

Temporal.TimeZone.prototype.equals ( _timeZoneLike_ )

-

- This method performs the following steps when called: -

- - 1. Let _timeZone_ be the *this* value. - 1. Perform ? RequireInternalSlot(_timeZone_, [[InitializedTemporalTimeZone]]). - 1. Let _other_ be ? ToTemporalTimeZoneSlotValue(_timeZoneLike_). - 1. Return ? TimeZoneEquals(_timeZone_, _other_). - -
-

Temporal.TimeZone.prototype.getOffsetNanosecondsFor ( _instant_ )