From bcf869a0a0ac1e307452ff5450ed2902d798285d Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Thu, 25 Feb 2021 14:38:17 -0800 Subject: [PATCH] WIP: Create time zone record from time zone objects Similar to calendar records, when constructing a new ZonedDateTime, eagerly get all the required time zone methods, and save them in a Record, which goes into the ZonedDateTime's [[TimeZoneRecord]] internal slot. _For internal use of the intrinsic ZonedDateTime constructor only_, in the polyfill the constructor accepts a time zone record object instead of a Temporal.TimeZone object. This has no observable effect on user code, because user code can never obtain a time zone record object. Still to do: - spec text - same problem as calendar records where the time zone record is lost when calling through user code - when calling a TimeZone method directly, we create a new time zone record first, which Gets all the methods. Maybe this isn't needed unless we're calling the method from ZonedDateTime where we have the record? See: #1294 --- .eslintrc.yml | 1 + polyfill/lib/ecmascript.mjs | 185 ++++++++++-------- polyfill/lib/intl.mjs | 8 +- polyfill/lib/now.mjs | 6 +- polyfill/lib/plaindate.mjs | 18 +- polyfill/lib/plaindatetime.mjs | 5 +- polyfill/lib/plaintime.mjs | 6 +- polyfill/lib/record.mjs | 10 + polyfill/lib/slots.mjs | 2 +- polyfill/lib/timezone.mjs | 9 +- polyfill/lib/zoneddatetime.mjs | 116 ++++++----- .../toString/timezone-no-tostring.js | 29 --- .../Instant/prototype/toString/timezone.js | 9 +- .../calendar-from-undefined.js | 9 +- .../toZonedDateTime/calendar-function.js | 10 +- .../toZonedDateTime/calendar-object.js | 10 +- .../prototype/toZonedDateTime/calendar.js | 7 +- .../toZonedDateTime/plain-custom-timezone.js | 12 +- .../toZonedDateTime/plain-custom-timezone.js | 10 +- .../getOffsetStringFor/custom-timezone.js | 8 +- .../getOffsetNanosecondsFor-undefined.js | 11 -- .../getPlainDateTimeFor/calendar-function.js | 6 +- .../getPlainDateTimeFor/calendar-object.js | 6 +- .../getPlainDateTimeFor/custom-timezone.js | 8 +- .../getOffsetNanosecondsFor-undefined.js | 21 -- .../constructor/timezone-undefined.js | 4 +- .../toPlainDateTime/plain-custom-timezone.js | 8 +- .../timezone-invalid-result.js | 14 +- polyfill/test/helpers/temporalHelpers.js | 8 +- .../now/plainDate/calendar-from-undefined.js | 10 +- .../test/now/plainDate/calendar-function.js | 6 +- .../test/now/plainDate/calendar-object.js | 6 +- polyfill/test/now/plainDate/calendar.js | 8 +- .../test/now/plainDate/timezone-object.js | 8 +- polyfill/test/now/plainDate/timezone.js | 8 +- .../test/now/plainDate/toDate-override.js | 8 +- .../plainDateTime/calendar-from-undefined.js | 10 +- .../now/plainDateTime/calendar-function.js | 6 +- .../test/now/plainDateTime/calendar-object.js | 6 +- polyfill/test/now/plainDateTime/calendar.js | 8 +- .../test/now/plainDateTime/timezone-object.js | 8 +- polyfill/test/now/plainDateTime/timezone.js | 8 +- .../test/now/plainTimeISO/timezone-object.js | 8 +- polyfill/test/now/plainTimeISO/timezone.js | 8 +- .../test/now/plainTimeISO/toTime-override.js | 8 +- 45 files changed, 370 insertions(+), 310 deletions(-) delete mode 100644 polyfill/test/Instant/prototype/toString/timezone-no-tostring.js delete mode 100644 polyfill/test/TimeZone/prototype/getOffsetStringFor/getOffsetNanosecondsFor-undefined.js delete mode 100644 polyfill/test/TimeZone/prototype/getPlainDateTimeFor/getOffsetNanosecondsFor-undefined.js diff --git a/.eslintrc.yml b/.eslintrc.yml index 4e64e74c48..15b83cd1ed 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -101,6 +101,7 @@ overrides: assert: readonly verifyProperty: readonly MINIMAL_CALENDAR_OBJECT: readonly + MINIMAL_TIME_ZONE_OBJECT: readonly # test262 code complies to a different coding style extends: 'eslint:recommended' rules: diff --git a/polyfill/lib/ecmascript.mjs b/polyfill/lib/ecmascript.mjs index c6b8669f60..3c0f8e30a8 100644 --- a/polyfill/lib/ecmascript.mjs +++ b/polyfill/lib/ecmascript.mjs @@ -30,7 +30,7 @@ import ToString from 'es-abstract/2020/ToString.js'; import Type from 'es-abstract/2020/Type.js'; import { GetIntrinsic } from './intrinsicclass.mjs'; -import { CalendarRecord } from './record.mjs'; +import { CalendarRecord, TimeZoneRecord } from './record.mjs'; import { GetSlot, HasSlot, @@ -50,7 +50,7 @@ import { DATE_BRAND, YEAR_MONTH_BRAND, MONTH_DAY_BRAND, - TIME_ZONE, + TIME_ZONE_RECORD, CALENDAR_RECORD, YEARS, MONTHS, @@ -125,7 +125,7 @@ const ES2020 = { export const ES = ObjectAssign({}, ES2020, { ToPositiveInteger: ToPositiveInteger, - IsTemporalInstant: (item) => HasSlot(item, EPOCHNANOSECONDS) && !HasSlot(item, TIME_ZONE, CALENDAR_RECORD), + IsTemporalInstant: (item) => HasSlot(item, EPOCHNANOSECONDS) && !HasSlot(item, TIME_ZONE_RECORD, CALENDAR_RECORD), IsTemporalTimeZone: (item) => HasSlot(item, TIMEZONE_ID), IsTemporalCalendar: (item) => HasSlot(item, CALENDAR_ID), IsTemporalDuration: (item) => @@ -149,7 +149,7 @@ export const ES = ObjectAssign({}, ES2020, { ), IsTemporalYearMonth: (item) => HasSlot(item, YEAR_MONTH_BRAND), IsTemporalMonthDay: (item) => HasSlot(item, MONTH_DAY_BRAND), - IsTemporalZonedDateTime: (item) => HasSlot(item, EPOCHNANOSECONDS, TIME_ZONE, CALENDAR_RECORD), + IsTemporalZonedDateTime: (item) => HasSlot(item, EPOCHNANOSECONDS, TIME_ZONE_RECORD, CALENDAR_RECORD), TemporalTimeZoneFromString: (stringIdent) => { let { ianaName, offset, z } = ES.ParseTemporalTimeZoneString(stringIdent); if (z) ianaName = 'UTC'; @@ -860,7 +860,8 @@ export const ES = ObjectAssign({}, ES2020, { const relativeTo = options.relativeTo; if (relativeTo === undefined) return relativeTo; - let year, month, day, hour, minute, second, millisecond, microsecond, nanosecond, calendarRecord, timeZone, offset; + let year, month, day, hour, minute, second, millisecond, microsecond, nanosecond, calendarRecord, timeZoneRecord; + let offset; if (ES.Type(relativeTo) === 'Object') { if (ES.IsTemporalZonedDateTime(relativeTo) || ES.IsTemporalDateTime(relativeTo)) return relativeTo; calendarRecord = ES.GetOrCreateCalendarRecord(relativeTo); @@ -878,7 +879,7 @@ export const ES = ObjectAssign({}, ES2020, { nanosecond } = ES.InterpretTemporalDateTimeFields(calendarRecord, fields, { overflow: 'constrain' })); offset = relativeTo.offset; - timeZone = relativeTo.timeZone; + timeZoneRecord = ES.GetOrCreateTimeZoneRecord(relativeTo); } else { let ianaName, calendar; ({ @@ -895,13 +896,12 @@ export const ES = ObjectAssign({}, ES2020, { ianaName, offset } = ES.ParseISODateTime(ES.ToString(relativeTo), { zoneRequired: false })); - if (ianaName) timeZone = ianaName; + if (ianaName) timeZoneRecord = ES.NewTimeZoneRecord(ES.ToTemporalTimeZone(ianaName)); if (!calendar) calendar = ES.GetISO8601Calendar(); calendar = ES.ToTemporalCalendar(calendar); calendarRecord = ES.NewCalendarRecord(calendar); } - if (timeZone) { - timeZone = ES.ToTemporalTimeZone(timeZone); + if (timeZoneRecord) { let offsetNs = null; if (offset) offsetNs = ES.ParseOffsetString(ES.ToString(offset)); const epochNanoseconds = ES.InterpretISODateTimeOffset( @@ -915,12 +915,12 @@ export const ES = ObjectAssign({}, ES2020, { microsecond, nanosecond, offsetNs, - timeZone, + timeZoneRecord, 'compatible', 'reject' ); const TemporalZonedDateTime = GetIntrinsic('%Temporal.ZonedDateTime%'); - return new TemporalZonedDateTime(epochNanoseconds, timeZone, calendarRecord); + return new TemporalZonedDateTime(epochNanoseconds, timeZoneRecord, calendarRecord); } const TemporalDateTime = GetIntrinsic('%Temporal.PlainDateTime%'); return new TemporalDateTime( @@ -1137,7 +1137,6 @@ export const ES = ObjectAssign({}, ES2020, { ['nanosecond', 0], ['offset', undefined], ['second', 0], - ['timeZone'], ['year', undefined] ]; // Add extra fields from the calendar at the end @@ -1400,7 +1399,7 @@ export const ES = ObjectAssign({}, ES2020, { microsecond, nanosecond, offsetNs, - timeZone, + timeZoneRecord, disambiguation, offsetOpt ) => { @@ -1410,7 +1409,7 @@ export const ES = ObjectAssign({}, ES2020, { if (offsetNs === null || offsetOpt === 'ignore') { // Simple case: ISO string without a TZ offset (or caller wants to ignore // the offset), so just convert DateTime to Instant in the given time zone - const instant = ES.BuiltinTimeZoneGetInstantFor(timeZone, dt, disambiguation); + const instant = ES.BuiltinTimeZoneGetInstantFor(timeZoneRecord, dt, disambiguation); return GetSlot(instant, EPOCHNANOSECONDS); } @@ -1435,9 +1434,9 @@ export const ES = ObjectAssign({}, ES2020, { } // "prefer" or "reject" - const possibleInstants = timeZone.getPossibleInstantsFor(dt); + const possibleInstants = ES.GetPossibleInstantsFor(timeZoneRecord, dt); for (const candidate of possibleInstants) { - const candidateOffset = ES.GetOffsetNanosecondsFor(timeZone, candidate); + const candidateOffset = ES.GetOffsetNanosecondsFor(timeZoneRecord, candidate); if (candidateOffset === offsetNs) return GetSlot(candidate, EPOCHNANOSECONDS); } @@ -1445,22 +1444,26 @@ export const ES = ObjectAssign({}, ES2020, { // zone and date/time. if (offsetOpt === 'reject') { const offsetStr = ES.FormatTimeZoneOffsetString(offsetNs); - const timeZoneString = ES.IsTemporalTimeZone(timeZone) ? GetSlot(timeZone, TIMEZONE_ID) : 'time zone'; + const timeZoneString = ES.IsTemporalTimeZone(timeZoneRecord.object) + ? GetSlot(timeZoneRecord.object, TIMEZONE_ID) + : 'time zone'; throw new RangeError(`Offset ${offsetStr} is invalid for ${dt} in ${timeZoneString}`); } // fall through: offsetOpt === 'prefer', but the offset doesn't match // so fall back to use the time zone instead. - const instant = ES.BuiltinTimeZoneGetInstantFor(timeZone, dt, disambiguation); + const instant = ES.BuiltinTimeZoneGetInstantFor(timeZoneRecord, dt, disambiguation); return GetSlot(instant, EPOCHNANOSECONDS); }, ToTemporalZonedDateTime: (item, constructor, options = {}) => { - let year, month, day, hour, minute, second, millisecond, microsecond, nanosecond, timeZone, offset, calendar; + let year, month, day, hour, minute, second, millisecond, microsecond, nanosecond, timeZoneRecord, offset, calendar; if (ES.Type(item) === 'Object') { if (ES.IsTemporalZonedDateTime(item)) return item; const calendarRecord = ES.GetOrCreateCalendarRecord(item); calendar = calendarRecord.object; const fieldNames = ES.CalendarFields(calendarRecord, ['day', 'month', 'year']); const fields = ES.ToTemporalZonedDateTimeFields(item, fieldNames); + timeZoneRecord = ES.GetOrCreateTimeZoneRecord(item); + if (!timeZoneRecord) throw new TypeError("required field 'timeZone' missing or undefined"); ({ year, month, @@ -1472,7 +1475,6 @@ export const ES = ObjectAssign({}, ES2020, { microsecond, nanosecond } = ES.InterpretTemporalDateTimeFields(calendarRecord, fields, options)); - timeZone = ES.ToTemporalTimeZone(fields.timeZone); offset = fields.offset; if (offset !== undefined) offset = ES.ToString(offset); } else { @@ -1493,7 +1495,7 @@ export const ES = ObjectAssign({}, ES2020, { calendar } = ES.ParseTemporalZonedDateTimeString(ES.ToString(item))); if (!ianaName) throw new RangeError('time zone ID required in brackets'); - timeZone = ES.TimeZoneFrom(ianaName); + timeZoneRecord = ES.NewTimeZoneRecord(ES.TimeZoneFrom(ianaName)); if (!calendar) calendar = ES.GetISO8601Calendar(); calendar = ES.ToTemporalCalendar(calendar); } @@ -1512,11 +1514,11 @@ export const ES = ObjectAssign({}, ES2020, { microsecond, nanosecond, offsetNs, - timeZone, + timeZoneRecord, disambiguation, offsetOpt ); - const result = new constructor(epochNanoseconds, timeZone, calendar); + const result = new constructor(epochNanoseconds, timeZoneRecord.object, calendar); if (!ES.IsTemporalZonedDateTime(result)) throw new TypeError('invalid result'); return result; }, @@ -1698,14 +1700,30 @@ export const ES = ObjectAssign({}, ES2020, { const identifier = ES.ToString(temporalTimeZoneLike); return ES.TimeZoneFrom(identifier); }, + NewTimeZoneRecord: (timeZone) => { + return new TimeZoneRecord(timeZone); + }, + IsTimeZoneRecord: (object) => { + return ES.Type(object) === 'Object' && object instanceof TimeZoneRecord; + }, + GetOrCreateTimeZoneRecord: (object) => { + if (HasSlot(object, TIME_ZONE_RECORD)) return GetSlot(object, TIME_ZONE_RECORD); + let { timeZone } = object; + if (timeZone === undefined) return undefined; + timeZone = ES.ToTemporalTimeZone(timeZone); + return new TimeZoneRecord(timeZone); + }, + TimeZoneToString: (timeZoneRecord) => { + return ES.Call(timeZoneRecord.toString, timeZoneRecord.object, []); + }, TimeZoneCompare: (one, two) => { - const tz1 = ES.ToString(one); - const tz2 = ES.ToString(two); + const tz1 = ES.TimeZoneToString(one); + const tz2 = ES.TimeZoneToString(two); return tz1 < tz2 ? -1 : tz1 > tz2 ? 1 : 0; }, TimeZoneEquals: (one, two) => { - const tz1 = ES.ToString(one); - const tz2 = ES.ToString(two); + const tz1 = ES.TimeZoneToString(one); + const tz2 = ES.TimeZoneToString(two); return tz1 === tz2; }, TemporalDateTimeToDate: (dateTime) => { @@ -1728,12 +1746,8 @@ export const ES = ObjectAssign({}, ES2020, { GetSlot(dateTime, ISO_NANOSECOND) ); }, - GetOffsetNanosecondsFor: (timeZone, instant) => { - let getOffsetNanosecondsFor = ES.GetMethod(timeZone, 'getOffsetNanosecondsFor'); - if (getOffsetNanosecondsFor === undefined) { - getOffsetNanosecondsFor = GetIntrinsic('%Temporal.TimeZone.prototype.getOffsetNanosecondsFor%'); - } - const offsetNs = ES.Call(getOffsetNanosecondsFor, timeZone, [instant]); + GetOffsetNanosecondsFor: (timeZoneRecord, instant) => { + const offsetNs = ES.Call(timeZoneRecord.getOffsetNanosecondsFor, timeZoneRecord.object, [instant]); if (typeof offsetNs !== 'number') { throw new TypeError('bad return from getOffsetNanosecondsFor'); } @@ -1742,13 +1756,13 @@ export const ES = ObjectAssign({}, ES2020, { } return offsetNs; }, - BuiltinTimeZoneGetOffsetStringFor: (timeZone, instant) => { - const offsetNs = ES.GetOffsetNanosecondsFor(timeZone, instant); + BuiltinTimeZoneGetOffsetStringFor: (timeZoneRecord, instant) => { + const offsetNs = ES.GetOffsetNanosecondsFor(timeZoneRecord, instant); return ES.FormatTimeZoneOffsetString(offsetNs); }, - BuiltinTimeZoneGetPlainDateTimeFor: (timeZone, instant, calendarRecord) => { + BuiltinTimeZoneGetPlainDateTimeFor: (timeZoneRecord, instant, calendarRecord) => { const ns = GetSlot(instant, EPOCHNANOSECONDS); - const offsetNs = ES.GetOffsetNanosecondsFor(timeZone, instant); + const offsetNs = ES.GetOffsetNanosecondsFor(timeZoneRecord, instant); let { year, month, day, hour, minute, second, millisecond, microsecond, nanosecond } = ES.GetISOPartsFromEpoch(ns); ({ year, month, day, hour, minute, second, millisecond, microsecond, nanosecond } = ES.BalanceISODateTime( year, @@ -1775,9 +1789,9 @@ export const ES = ObjectAssign({}, ES2020, { calendarRecord ); }, - BuiltinTimeZoneGetInstantFor: (timeZone, dateTime, disambiguation) => { + BuiltinTimeZoneGetInstantFor: (timeZoneRecord, dateTime, disambiguation) => { const Instant = GetIntrinsic('%Temporal.Instant%'); - const possibleInstants = ES.GetPossibleInstantsFor(timeZone, dateTime); + const possibleInstants = ES.GetPossibleInstantsFor(timeZoneRecord, dateTime); const numInstants = possibleInstants.length; if (numInstants === 1) return possibleInstants[0]; @@ -1809,20 +1823,20 @@ export const ES = ObjectAssign({}, ES2020, { if (utcns === null) throw new RangeError('DateTime outside of supported range'); const dayBefore = new Instant(utcns.minus(86400e9)); const dayAfter = new Instant(utcns.plus(86400e9)); - const offsetBefore = ES.GetOffsetNanosecondsFor(timeZone, dayBefore); - const offsetAfter = ES.GetOffsetNanosecondsFor(timeZone, dayAfter); + const offsetBefore = ES.GetOffsetNanosecondsFor(timeZoneRecord, dayBefore); + const offsetAfter = ES.GetOffsetNanosecondsFor(timeZoneRecord, dayAfter); const nanoseconds = offsetAfter - offsetBefore; const diff = ES.ToTemporalDurationRecord({ nanoseconds }, 'reject'); switch (disambiguation) { case 'earlier': { const earlier = dateTime.subtract(diff); - return ES.GetPossibleInstantsFor(timeZone, earlier)[0]; + return ES.GetPossibleInstantsFor(timeZoneRecord, earlier)[0]; } case 'compatible': // fall through because 'compatible' means 'later' for "spring forward" transitions case 'later': { const later = dateTime.add(diff); - const possible = ES.GetPossibleInstantsFor(timeZone, later); + const possible = ES.GetPossibleInstantsFor(timeZoneRecord, later); return possible[possible.length - 1]; } case 'reject': { @@ -1830,9 +1844,8 @@ export const ES = ObjectAssign({}, ES2020, { } } }, - GetPossibleInstantsFor: (timeZone, dateTime) => { - let getPossibleInstantsFor = ES.GetMethod(timeZone, 'getPossibleInstantsFor'); - const possibleInstants = ES.Call(getPossibleInstantsFor, timeZone, [dateTime]); + GetPossibleInstantsFor: (timeZoneRecord, dateTime) => { + const possibleInstants = ES.Call(timeZoneRecord.getPossibleInstantsFor, timeZoneRecord.object, [dateTime]); const result = ES.CreateListFromArrayLike(possibleInstants, ['Object']); const numInstants = result.length; for (let ix = 0; ix < numInstants; ix++) { @@ -1877,7 +1890,8 @@ export const ES = ObjectAssign({}, ES2020, { outputTimeZone = new TemporalTimeZone('UTC'); } const iso = ES.NewCalendarRecord(ES.GetISO8601Calendar()); - const dateTime = ES.BuiltinTimeZoneGetPlainDateTimeFor(outputTimeZone, instant, iso); + const timeZoneRecord = ES.NewTimeZoneRecord(outputTimeZone); + const dateTime = ES.BuiltinTimeZoneGetPlainDateTimeFor(timeZoneRecord, instant, iso); const year = ES.ISOYearString(GetSlot(dateTime, ISO_YEAR)); const month = ES.ISODateTimePartString(GetSlot(dateTime, ISO_MONTH)); const day = ES.ISODateTimePartString(GetSlot(dateTime, ISO_DAY)); @@ -1891,7 +1905,7 @@ export const ES = ObjectAssign({}, ES2020, { precision ); let timeZoneString = 'Z'; - if (timeZone !== undefined) timeZoneString = ES.BuiltinTimeZoneGetOffsetStringFor(outputTimeZone, instant); + if (timeZone !== undefined) timeZoneString = ES.BuiltinTimeZoneGetOffsetStringFor(timeZoneRecord, instant); return `${year}-${month}-${day}T${hour}:${minute}${seconds}${timeZoneString}`; }, TemporalDurationToString: (duration, precision = 'auto', options = undefined) => { @@ -2349,12 +2363,12 @@ export const ES = ObjectAssign({}, ES2020, { const start = GetSlot(relativeTo, INSTANT); const endNs = startNs.add(nanoseconds); const end = new TemporalInstant(endNs); - const timeZone = GetSlot(relativeTo, TIME_ZONE); + const timeZoneRecord = GetSlot(relativeTo, TIME_ZONE_RECORD); const calendarRecord = GetSlot(relativeTo, CALENDAR_RECORD); // Find the difference in days only. - const dtStart = ES.BuiltinTimeZoneGetPlainDateTimeFor(timeZone, start, calendarRecord); - const dtEnd = ES.BuiltinTimeZoneGetPlainDateTimeFor(timeZone, end, calendarRecord); + const dtStart = ES.BuiltinTimeZoneGetPlainDateTimeFor(timeZoneRecord, start, calendarRecord); + const dtEnd = ES.BuiltinTimeZoneGetPlainDateTimeFor(timeZoneRecord, end, calendarRecord); let { days } = ES.DifferenceISODateTime( GetSlot(dtStart, ISO_YEAR), GetSlot(dtStart, ISO_MONTH), @@ -2377,7 +2391,7 @@ export const ES = ObjectAssign({}, ES2020, { calendarRecord, 'days' ); - let intermediateNs = ES.AddZonedDateTime(start, timeZone, calendarRecord, 0, 0, 0, days, 0, 0, 0, 0, 0, 0); + let intermediateNs = ES.AddZonedDateTime(start, timeZoneRecord, calendarRecord, 0, 0, 0, days, 0, 0, 0, 0, 0, 0); // may disambiguate // If clock time after addition was in the middle of a skipped period, the @@ -2391,7 +2405,7 @@ export const ES = ObjectAssign({}, ES2020, { if (sign === 1) { while (days > 0 && intermediateNs.greater(endNs)) { --days; - intermediateNs = ES.AddZonedDateTime(start, timeZone, calendarRecord, 0, 0, 0, days, 0, 0, 0, 0, 0, 0); + intermediateNs = ES.AddZonedDateTime(start, timeZoneRecord, calendarRecord, 0, 0, 0, days, 0, 0, 0, 0, 0, 0); // may do disambiguation } } @@ -2403,7 +2417,7 @@ export const ES = ObjectAssign({}, ES2020, { // calculate length of the next day (day that contains the time remainder) const oneDayFartherNs = ES.AddZonedDateTime( relativeInstant, - timeZone, + timeZoneRecord, calendarRecord, 0, 0, @@ -2441,7 +2455,7 @@ export const ES = ObjectAssign({}, ES2020, { if (ES.IsTemporalZonedDateTime(relativeTo)) { const endNs = ES.AddZonedDateTime( GetSlot(relativeTo, INSTANT), - GetSlot(relativeTo, TIME_ZONE), + GetSlot(relativeTo, TIME_ZONE_RECORD), GetSlot(relativeTo, CALENDAR_RECORD), 0, 0, @@ -2706,13 +2720,13 @@ export const ES = ObjectAssign({}, ES2020, { CalculateOffsetShift: (relativeTo, y, mon, w, d, h, min, s, ms, µs, ns) => { if (ES.IsTemporalZonedDateTime(relativeTo)) { const instant = GetSlot(relativeTo, INSTANT); - const timeZone = GetSlot(relativeTo, TIME_ZONE); + const timeZoneRecord = GetSlot(relativeTo, TIME_ZONE_RECORD); const calendarRecord = GetSlot(relativeTo, CALENDAR_RECORD); - const offsetBefore = ES.GetOffsetNanosecondsFor(timeZone, instant); - const after = ES.AddZonedDateTime(instant, timeZone, calendarRecord, y, mon, w, d, h, min, s, ms, µs, ns); + const offsetBefore = ES.GetOffsetNanosecondsFor(timeZoneRecord, instant); + const after = ES.AddZonedDateTime(instant, timeZoneRecord, calendarRecord, y, mon, w, d, h, min, s, ms, µs, ns); const TemporalInstant = GetIntrinsic('%Temporal.Instant%'); const instantAfter = new TemporalInstant(after); - const offsetAfter = ES.GetOffsetNanosecondsFor(timeZone, instantAfter); + const offsetAfter = ES.GetOffsetNanosecondsFor(timeZoneRecord, instantAfter); return offsetAfter - offsetBefore; } return 0; @@ -3030,7 +3044,7 @@ export const ES = ObjectAssign({}, ES2020, { )); return { years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds }; }, - DifferenceZonedDateTime: (ns1, ns2, timeZone, calendarRecord, largestUnit, options) => { + DifferenceZonedDateTime: (ns1, ns2, timeZoneRecord, calendarRecord, largestUnit, options) => { const nsDiff = ns2.subtract(ns1); if (nsDiff.isZero()) { return { @@ -3051,8 +3065,8 @@ export const ES = ObjectAssign({}, ES2020, { const TemporalInstant = GetIntrinsic('%Temporal.Instant%'); const start = new TemporalInstant(ns1); const end = new TemporalInstant(ns2); - const dtStart = ES.BuiltinTimeZoneGetPlainDateTimeFor(timeZone, start, calendarRecord); - const dtEnd = ES.BuiltinTimeZoneGetPlainDateTimeFor(timeZone, end, calendarRecord); + const dtStart = ES.BuiltinTimeZoneGetPlainDateTimeFor(timeZoneRecord, start, calendarRecord); + const dtEnd = ES.BuiltinTimeZoneGetPlainDateTimeFor(timeZoneRecord, end, calendarRecord); let { years, months, weeks, days } = ES.DifferenceISODateTime( GetSlot(dtStart, ISO_YEAR), GetSlot(dtStart, ISO_MONTH), @@ -3078,7 +3092,7 @@ export const ES = ObjectAssign({}, ES2020, { ); let intermediateNs = ES.AddZonedDateTime( start, - timeZone, + timeZoneRecord, calendarRecord, years, months, @@ -3094,7 +3108,7 @@ export const ES = ObjectAssign({}, ES2020, { // may disambiguate let timeRemainderNs = ns2.subtract(intermediateNs); const TemporalZonedDateTime = GetIntrinsic('%Temporal.ZonedDateTime%'); - const intermediate = new TemporalZonedDateTime(intermediateNs, timeZone, calendarRecord); + const intermediate = new TemporalZonedDateTime(intermediateNs, timeZoneRecord, calendarRecord); ({ nanoseconds: timeRemainderNs, days } = ES.NanosecondsToDays(timeRemainderNs, intermediate)); // Finally, merge the date and time durations and return the merged result. @@ -3238,11 +3252,11 @@ export const ES = ObjectAssign({}, ES2020, { } else { // relativeTo is a ZonedDateTime const TemporalInstant = GetIntrinsic('%Temporal.Instant%'); - const timeZone = GetSlot(relativeTo, TIME_ZONE); + const timeZoneRecord = GetSlot(relativeTo, TIME_ZONE_RECORD); const calendarRecord = GetSlot(relativeTo, CALENDAR_RECORD); const intermediateNs = ES.AddZonedDateTime( GetSlot(relativeTo, INSTANT), - timeZone, + timeZoneRecord, calendarRecord, y1, mon1, @@ -3257,7 +3271,7 @@ export const ES = ObjectAssign({}, ES2020, { ); const endNs = ES.AddZonedDateTime( new TemporalInstant(intermediateNs), - timeZone, + timeZoneRecord, calendarRecord, y2, mon2, @@ -3308,7 +3322,7 @@ export const ES = ObjectAssign({}, ES2020, { } = ES.DifferenceZonedDateTime( GetSlot(relativeTo, EPOCHNANOSECONDS), endNs, - timeZone, + timeZoneRecord, calendarRecord, largestUnit )); @@ -3391,7 +3405,22 @@ export const ES = ObjectAssign({}, ES2020, { nanosecond }; }, - AddZonedDateTime: (instant, timeZone, calendarRecord, years, months, weeks, days, h, min, s, ms, µs, ns, options) => { + AddZonedDateTime: ( + instant, + timeZoneRecord, + calendarRecord, + years, + months, + weeks, + days, + h, + min, + s, + ms, + µs, + ns, + options + ) => { // If only time is to be added, then use Instant math. It's not OK to fall // through to the date/time code below because compatible disambiguation in // the PlainDateTime=>Instant conversion will change the offset of any @@ -3407,7 +3436,7 @@ export const ES = ObjectAssign({}, ES2020, { // RFC 5545 requires the date portion to be added in calendar days and the // time portion to be added in exact time. - let dt = ES.BuiltinTimeZoneGetPlainDateTimeFor(timeZone, instant, calendarRecord); + let dt = ES.BuiltinTimeZoneGetPlainDateTimeFor(timeZoneRecord, instant, calendarRecord); const TemporalDate = GetIntrinsic('%Temporal.PlainDate%'); const datePart = new TemporalDate( GetSlot(dt, ISO_YEAR), @@ -3433,7 +3462,7 @@ export const ES = ObjectAssign({}, ES2020, { // Note that 'compatible' is used below because this disambiguation behavior // is required by RFC 5545. - const instantIntermediate = ES.BuiltinTimeZoneGetInstantFor(timeZone, dtIntermediate, 'compatible'); + const instantIntermediate = ES.BuiltinTimeZoneGetInstantFor(timeZoneRecord, dtIntermediate, 'compatible'); return ES.AddInstant(GetSlot(instantIntermediate, EPOCHNANOSECONDS), h, min, s, ms, µs, ns); }, RoundNumberToIncrement: (quantity, increment, mode) => { @@ -3581,11 +3610,11 @@ export const ES = ObjectAssign({}, ES2020, { return { relativeTo, days }; }, MoveRelativeZonedDateTime: (relativeTo, years, months, weeks, days) => { - const timeZone = GetSlot(relativeTo, TIME_ZONE); + const timeZoneRecord = GetSlot(relativeTo, TIME_ZONE_RECORD); const calendarRecord = GetSlot(relativeTo, CALENDAR_RECORD); const intermediateNs = ES.AddZonedDateTime( GetSlot(relativeTo, INSTANT), - timeZone, + timeZoneRecord, calendarRecord, years, months, @@ -3599,7 +3628,7 @@ export const ES = ObjectAssign({}, ES2020, { 0 ); const TemporalZonedDateTime = GetIntrinsic('%Temporal.ZonedDateTime%'); - return new TemporalZonedDateTime(intermediateNs, timeZone, calendarRecord); + return new TemporalZonedDateTime(intermediateNs, timeZoneRecord, calendarRecord); }, AdjustRoundedDurationDays: ( years, @@ -3648,11 +3677,11 @@ export const ES = ObjectAssign({}, ES2020, { ); const direction = MathSign(timeRemainderNs.toJSNumber()); - const timeZone = GetSlot(relativeTo, TIME_ZONE); + const timeZoneRecord = GetSlot(relativeTo, TIME_ZONE_RECORD); const calendarRecord = GetSlot(relativeTo, CALENDAR_RECORD); const dayStart = ES.AddZonedDateTime( GetSlot(relativeTo, INSTANT), - timeZone, + timeZoneRecord, calendarRecord, years, months, @@ -3668,7 +3697,7 @@ export const ES = ObjectAssign({}, ES2020, { const TemporalInstant = GetIntrinsic('%Temporal.Instant%'); const dayEnd = ES.AddZonedDateTime( new TemporalInstant(dayStart), - timeZone, + timeZoneRecord, calendarRecord, 0, 0, @@ -3744,7 +3773,7 @@ export const ES = ObjectAssign({}, ES2020, { if (ES.IsTemporalZonedDateTime(relativeTo)) { zdtRelative = relativeTo; relativeTo = ES.BuiltinTimeZoneGetPlainDateTimeFor( - GetSlot(relativeTo, TIME_ZONE), + GetSlot(relativeTo, TIME_ZONE_RECORD), GetSlot(relativeTo, INSTANT), GetSlot(relativeTo, CALENDAR_RECORD) ); diff --git a/polyfill/lib/intl.mjs b/polyfill/lib/intl.mjs index 01153eb8ba..054100de1d 100644 --- a/polyfill/lib/intl.mjs +++ b/polyfill/lib/intl.mjs @@ -13,7 +13,7 @@ import { ISO_MICROSECOND, ISO_NANOSECOND, CALENDAR_RECORD, - TIME_ZONE + TIME_ZONE_RECORD } from './slots.mjs'; import { TimeZone } from './timezone.mjs'; @@ -47,7 +47,7 @@ export function DateTimeFormat(locale = IntlDateTimeFormat().resolvedOptions().l this[TZ_GIVEN] = options.timeZone ? options.timeZone : null; this[ORIGINAL] = new IntlDateTimeFormat(locale, options); - this[TZ_RESOLVED] = new TimeZone(this.resolvedOptions().timeZone); + this[TZ_RESOLVED] = ES.NewTimeZoneRecord(new TimeZone(this.resolvedOptions().timeZone)); this[CAL_ID] = this.resolvedOptions().calendar; this[DATE] = new IntlDateTimeFormat(locale, dateAmend(options)); this[YM] = new IntlDateTimeFormat(locale, yearMonthAmend(options)); @@ -368,8 +368,8 @@ function extractOverrides(temporalObj, main) { ); } - let timeZone = GetSlot(temporalObj, TIME_ZONE); - const objTimeZone = ES.ToString(timeZone); + let timeZoneRecord = GetSlot(temporalObj, TIME_ZONE_RECORD); + const objTimeZone = ES.TimeZoneToString(timeZoneRecord); if (main[TZ_GIVEN] && main[TZ_GIVEN] !== objTimeZone) { throw new RangeError(`timeZone option ${main[TZ_GIVEN]} doesn't match actual time zone ${objTimeZone}`); } diff --git a/polyfill/lib/now.mjs b/polyfill/lib/now.mjs index 8aeeabb4c2..84b80fdd23 100644 --- a/polyfill/lib/now.mjs +++ b/polyfill/lib/now.mjs @@ -19,17 +19,19 @@ function instant() { } function plainDateTime(calendarLike, temporalTimeZoneLike = timeZone()) { const timeZone = ES.ToTemporalTimeZone(temporalTimeZoneLike); + const timeZoneRecord = ES.NewTimeZoneRecord(timeZone); const calendar = ES.ToTemporalCalendar(calendarLike); const calendarRecord = ES.NewCalendarRecord(calendar); const inst = instant(); - return ES.BuiltinTimeZoneGetPlainDateTimeFor(timeZone, inst, calendarRecord); + return ES.BuiltinTimeZoneGetPlainDateTimeFor(timeZoneRecord, inst, calendarRecord); } function plainDateTimeISO(temporalTimeZoneLike = timeZone()) { const timeZone = ES.ToTemporalTimeZone(temporalTimeZoneLike); + const timeZoneRecord = ES.NewTimeZoneRecord(timeZone); const calendar = ES.GetISO8601Calendar(); const calendarRecord = ES.NewCalendarRecord(calendar); const inst = instant(); - return ES.BuiltinTimeZoneGetPlainDateTimeFor(timeZone, inst, calendarRecord); + return ES.BuiltinTimeZoneGetPlainDateTimeFor(timeZoneRecord, inst, calendarRecord); } function zonedDateTime(calendarLike, temporalTimeZoneLike = timeZone()) { const timeZone = ES.ToTemporalTimeZone(temporalTimeZoneLike); diff --git a/polyfill/lib/plaindate.mjs b/polyfill/lib/plaindate.mjs index 0cf2e5ccaa..2e0ea48f53 100644 --- a/polyfill/lib/plaindate.mjs +++ b/polyfill/lib/plaindate.mjs @@ -355,18 +355,12 @@ export class PlainDate { toZonedDateTime(item) { if (!ES.IsTemporalDate(this)) throw new TypeError('invalid receiver'); - let timeZone, temporalTime; + let timeZoneRecord, temporalTime; if (ES.Type(item) === 'Object') { - let timeZoneLike = item.timeZone; - if (timeZoneLike === undefined) { - timeZone = ES.ToTemporalTimeZone(item); - } else { - timeZone = ES.ToTemporalTimeZone(timeZoneLike); - temporalTime = item.plainTime; - } - } else { - timeZone = ES.ToTemporalTimeZone(item); + timeZoneRecord = ES.GetOrCreateTimeZoneRecord(item); + if (timeZoneRecord) temporalTime = item.plainTime; } + if (!timeZoneRecord) timeZoneRecord = ES.NewTimeZoneRecord(ES.ToTemporalTimeZone(item)); const year = GetSlot(this, ISO_YEAR); const month = GetSlot(this, ISO_MONTH); @@ -402,9 +396,9 @@ export class PlainDate { nanosecond, calendarRecord ); - const instant = ES.BuiltinTimeZoneGetInstantFor(timeZone, dt, 'compatible'); + const instant = ES.BuiltinTimeZoneGetInstantFor(timeZoneRecord, dt, 'compatible'); const ZonedDateTime = GetIntrinsic('%Temporal.ZonedDateTime%'); - return new ZonedDateTime(GetSlot(instant, EPOCHNANOSECONDS), timeZone, calendarRecord); + return new ZonedDateTime(GetSlot(instant, EPOCHNANOSECONDS), timeZoneRecord, calendarRecord); } toPlainYearMonth() { if (!ES.IsTemporalDate(this)) throw new TypeError('invalid receiver'); diff --git a/polyfill/lib/plaindatetime.mjs b/polyfill/lib/plaindatetime.mjs index 86c0815170..125398ef02 100644 --- a/polyfill/lib/plaindatetime.mjs +++ b/polyfill/lib/plaindatetime.mjs @@ -728,11 +728,12 @@ export class PlainDateTime { toZonedDateTime(temporalTimeZoneLike, options = undefined) { if (!ES.IsTemporalDateTime(this)) throw new TypeError('invalid receiver'); const timeZone = ES.ToTemporalTimeZone(temporalTimeZoneLike); + const timeZoneRecord = ES.NewTimeZoneRecord(timeZone); options = ES.NormalizeOptionsObject(options); const disambiguation = ES.ToTemporalDisambiguation(options); - const instant = ES.BuiltinTimeZoneGetInstantFor(timeZone, this, disambiguation); + const instant = ES.BuiltinTimeZoneGetInstantFor(timeZoneRecord, this, disambiguation); const ZonedDateTime = GetIntrinsic('%Temporal.ZonedDateTime%'); - return new ZonedDateTime(GetSlot(instant, EPOCHNANOSECONDS), timeZone, GetSlot(this, CALENDAR_RECORD)); + return new ZonedDateTime(GetSlot(instant, EPOCHNANOSECONDS), timeZoneRecord, GetSlot(this, CALENDAR_RECORD)); } toPlainDate() { if (!ES.IsTemporalDateTime(this)) throw new TypeError('invalid receiver'); diff --git a/polyfill/lib/plaintime.mjs b/polyfill/lib/plaintime.mjs index 8abdcf38df..a057b97f43 100644 --- a/polyfill/lib/plaintime.mjs +++ b/polyfill/lib/plaintime.mjs @@ -461,7 +461,7 @@ export class PlainTime { if (timeZoneLike === undefined) { throw new TypeError('missing timeZone property'); } - const timeZone = ES.ToTemporalTimeZone(timeZoneLike); + const timeZoneRecord = ES.NewTimeZoneRecord(ES.ToTemporalTimeZone(timeZoneLike)); const year = GetSlot(temporalDate, ISO_YEAR); const month = GetSlot(temporalDate, ISO_MONTH); @@ -487,9 +487,9 @@ export class PlainTime { nanosecond, calendarRecord ); - const instant = ES.BuiltinTimeZoneGetInstantFor(timeZone, dt, 'compatible'); + const instant = ES.BuiltinTimeZoneGetInstantFor(timeZoneRecord, dt, 'compatible'); const ZonedDateTime = GetIntrinsic('%Temporal.ZonedDateTime%'); - return new ZonedDateTime(GetSlot(instant, EPOCHNANOSECONDS), timeZone, calendarRecord); + return new ZonedDateTime(GetSlot(instant, EPOCHNANOSECONDS), timeZoneRecord, calendarRecord); } getISOFields() { if (!ES.IsTemporalTime(this)) throw new TypeError('invalid receiver'); diff --git a/polyfill/lib/record.mjs b/polyfill/lib/record.mjs index 58c37d4b28..46f2f86f74 100644 --- a/polyfill/lib/record.mjs +++ b/polyfill/lib/record.mjs @@ -42,3 +42,13 @@ export class CalendarRecord { this.toString = requireCallable(calendar, 'toString'); } } + +export class TimeZoneRecord { + constructor(timeZone) { + if (Type(timeZone) !== 'Object') throw new TypeError('time zone must be an object'); + this.object = timeZone; + this.getOffsetNanosecondsFor = requireCallable(timeZone, 'getOffsetNanosecondsFor'); + this.getPossibleInstantsFor = requireCallableOrUndefined(timeZone, 'getPossibleInstantsFor'); + this.toString = requireCallable(timeZone, 'toString'); + } +} diff --git a/polyfill/lib/slots.mjs b/polyfill/lib/slots.mjs index 1103112897..711d417e4b 100644 --- a/polyfill/lib/slots.mjs +++ b/polyfill/lib/slots.mjs @@ -22,7 +22,7 @@ export const MONTH_DAY_BRAND = 'slot-month-day-brand'; // ZonedDateTime export const INSTANT = 'slot-cached-instant'; -export const TIME_ZONE = 'slot-time-zone'; +export const TIME_ZONE_RECORD = 'slot-time-zone-record'; // Duration export const YEARS = 'slot-years'; diff --git a/polyfill/lib/timezone.mjs b/polyfill/lib/timezone.mjs index e579bd5745..619d1d924d 100644 --- a/polyfill/lib/timezone.mjs +++ b/polyfill/lib/timezone.mjs @@ -55,19 +55,22 @@ export class TimeZone { } getOffsetStringFor(instant) { instant = ES.ToTemporalInstant(instant, GetIntrinsic('%Temporal.Instant%')); - return ES.BuiltinTimeZoneGetOffsetStringFor(this, instant); + const timeZoneRecord = ES.NewTimeZoneRecord(this); + return ES.BuiltinTimeZoneGetOffsetStringFor(timeZoneRecord, instant); } getPlainDateTimeFor(instant, calendar = ES.GetISO8601Calendar()) { instant = ES.ToTemporalInstant(instant, GetIntrinsic('%Temporal.Instant%')); calendar = ES.ToTemporalCalendar(calendar); + const timeZoneRecord = ES.NewTimeZoneRecord(this); const calendarRecord = ES.NewCalendarRecord(calendar); - return ES.BuiltinTimeZoneGetPlainDateTimeFor(this, instant, calendarRecord); + return ES.BuiltinTimeZoneGetPlainDateTimeFor(timeZoneRecord, instant, calendarRecord); } getInstantFor(dateTime, options = undefined) { dateTime = ES.ToTemporalDateTime(dateTime, GetIntrinsic('%Temporal.PlainDateTime%')); options = ES.NormalizeOptionsObject(options); const disambiguation = ES.ToTemporalDisambiguation(options); - return ES.BuiltinTimeZoneGetInstantFor(this, dateTime, disambiguation); + const timeZoneRecord = ES.NewTimeZoneRecord(this); + return ES.BuiltinTimeZoneGetInstantFor(timeZoneRecord, dateTime, disambiguation); } getPossibleInstantsFor(dateTime) { if (!ES.IsTemporalTimeZone(this)) throw new TypeError('invalid receiver'); diff --git a/polyfill/lib/zoneddatetime.mjs b/polyfill/lib/zoneddatetime.mjs index b82ffcebee..f897b8bd95 100644 --- a/polyfill/lib/zoneddatetime.mjs +++ b/polyfill/lib/zoneddatetime.mjs @@ -16,7 +16,7 @@ import { ISO_MINUTE, ISO_NANOSECOND, ISO_SECOND, - TIME_ZONE, + TIME_ZONE_RECORD, CreateSlots, GetSlot, SetSlot @@ -36,7 +36,13 @@ export class ZonedDateTime { throw new TypeError('missing argument: epochNanoseconds is required'); } epochNanoseconds = ES.ToBigInt(epochNanoseconds); - timeZone = ES.ToTemporalTimeZone(timeZone); + let timeZoneRecord; + if (ES.IsTimeZoneRecord(timeZone)) { + timeZoneRecord = timeZone; + timeZone = timeZone.object; + } else { + timeZone = ES.ToTemporalTimeZone(timeZone); + } let calendarRecord; if (ES.IsCalendarRecord(calendar)) { calendarRecord = calendar; @@ -46,11 +52,12 @@ export class ZonedDateTime { } ES.RejectInstantRange(epochNanoseconds); + if (!timeZoneRecord) timeZoneRecord = ES.NewTimeZoneRecord(timeZone); if (!calendarRecord) calendarRecord = ES.NewCalendarRecord(calendar); CreateSlots(this); SetSlot(this, EPOCHNANOSECONDS, epochNanoseconds); - SetSlot(this, TIME_ZONE, timeZone); + SetSlot(this, TIME_ZONE_RECORD, timeZoneRecord); SetSlot(this, CALENDAR_RECORD, calendarRecord); const TemporalInstant = GetIntrinsic('%Temporal.Instant%'); @@ -72,7 +79,7 @@ export class ZonedDateTime { } get timeZone() { if (!ES.IsTemporalZonedDateTime(this)) throw new TypeError('invalid receiver'); - return GetSlot(this, TIME_ZONE); + return GetSlot(this, TIME_ZONE_RECORD).object; } get year() { if (!ES.IsTemporalZonedDateTime(this)) throw new TypeError('invalid receiver'); @@ -163,9 +170,12 @@ export class ZonedDateTime { const today = new DateTime(year, month, day, 0, 0, 0, 0, 0, 0); const tomorrowFields = ES.AddISODate(year, month, day, 0, 0, 0, 1, 'reject'); const tomorrow = new DateTime(tomorrowFields.year, tomorrowFields.month, tomorrowFields.day, 0, 0, 0, 0, 0, 0); - const timeZone = GetSlot(this, TIME_ZONE); - const todayNs = GetSlot(ES.BuiltinTimeZoneGetInstantFor(timeZone, today, 'compatible'), EPOCHNANOSECONDS); - const tomorrowNs = GetSlot(ES.BuiltinTimeZoneGetInstantFor(timeZone, tomorrow, 'compatible'), EPOCHNANOSECONDS); + const timeZoneRecord = GetSlot(this, TIME_ZONE_RECORD); + const todayNs = GetSlot(ES.BuiltinTimeZoneGetInstantFor(timeZoneRecord, today, 'compatible'), EPOCHNANOSECONDS); + const tomorrowNs = GetSlot( + ES.BuiltinTimeZoneGetInstantFor(timeZoneRecord, tomorrow, 'compatible'), + EPOCHNANOSECONDS + ); return tomorrowNs.subtract(todayNs).toJSNumber() / 3.6e12; } get daysInWeek() { @@ -190,11 +200,11 @@ export class ZonedDateTime { } get offset() { if (!ES.IsTemporalZonedDateTime(this)) throw new TypeError('invalid receiver'); - return ES.BuiltinTimeZoneGetOffsetStringFor(GetSlot(this, TIME_ZONE), GetSlot(this, INSTANT)); + return ES.BuiltinTimeZoneGetOffsetStringFor(GetSlot(this, TIME_ZONE_RECORD), GetSlot(this, INSTANT)); } get offsetNanoseconds() { if (!ES.IsTemporalZonedDateTime(this)) throw new TypeError('invalid receiver'); - return ES.GetOffsetNanosecondsFor(GetSlot(this, TIME_ZONE), GetSlot(this, INSTANT)); + return ES.GetOffsetNanosecondsFor(GetSlot(this, TIME_ZONE_RECORD), GetSlot(this, INSTANT)); } with(temporalZonedDateTimeLike, options = undefined) { if (!ES.IsTemporalZonedDateTime(this)) throw new TypeError('invalid receiver'); @@ -212,7 +222,7 @@ export class ZonedDateTime { const disambiguation = ES.ToTemporalDisambiguation(options); const offset = ES.ToTemporalOffset(options, 'prefer'); - const timeZone = GetSlot(this, TIME_ZONE); + const timeZoneRecord = GetSlot(this, TIME_ZONE_RECORD); const calendarRecord = GetSlot(this, CALENDAR_RECORD); const fieldNames = ES.CalendarFields(calendarRecord, [ 'day', @@ -256,13 +266,13 @@ export class ZonedDateTime { microsecond, nanosecond, offsetNs, - timeZone, + timeZoneRecord, disambiguation, offset ); const Construct = ES.SpeciesConstructor(this, ZonedDateTime); - const result = new Construct(epochNanoseconds, GetSlot(this, TIME_ZONE), calendarRecord.object); + const result = new Construct(epochNanoseconds, timeZoneRecord.object, calendarRecord.object); if (!ES.IsTemporalZonedDateTime(result)) throw new TypeError('invalid result'); return result; } @@ -284,7 +294,7 @@ export class ZonedDateTime { const nanosecond = GetSlot(thisDt, ISO_NANOSECOND); calendarRecord = ES.ConsolidateCalendars(GetSlot(this, CALENDAR_RECORD), calendarRecord); - const timeZone = GetSlot(this, TIME_ZONE); + const timeZoneRecord = GetSlot(this, TIME_ZONE_RECORD); const PlainDateTime = GetIntrinsic('%Temporal.PlainDateTime%'); const dt = new PlainDateTime( year, @@ -298,9 +308,9 @@ export class ZonedDateTime { nanosecond, calendarRecord ); - const instant = ES.BuiltinTimeZoneGetInstantFor(timeZone, dt, 'compatible'); + const instant = ES.BuiltinTimeZoneGetInstantFor(timeZoneRecord, dt, 'compatible'); const Construct = ES.SpeciesConstructor(this, ZonedDateTime); - return new Construct(GetSlot(instant, EPOCHNANOSECONDS), timeZone, calendarRecord.object); + return new Construct(GetSlot(instant, EPOCHNANOSECONDS), timeZoneRecord.object, calendarRecord.object); } withPlainTime(temporalTime = undefined) { if (!ES.IsTemporalZonedDateTime(this)) throw new TypeError('invalid receiver'); @@ -320,7 +330,7 @@ export class ZonedDateTime { const microsecond = GetSlot(temporalTime, ISO_MICROSECOND); const nanosecond = GetSlot(temporalTime, ISO_NANOSECOND); - const timeZone = GetSlot(this, TIME_ZONE); + const timeZoneRecord = GetSlot(this, TIME_ZONE_RECORD); const PlainDateTime = GetIntrinsic('%Temporal.PlainDateTime%'); const dt = new PlainDateTime( year, @@ -334,9 +344,9 @@ export class ZonedDateTime { nanosecond, calendarRecord ); - const instant = ES.BuiltinTimeZoneGetInstantFor(timeZone, dt, 'compatible'); + const instant = ES.BuiltinTimeZoneGetInstantFor(timeZoneRecord, dt, 'compatible'); const Construct = ES.SpeciesConstructor(this, ZonedDateTime); - return new Construct(GetSlot(instant, EPOCHNANOSECONDS), timeZone, calendarRecord.object); + return new Construct(GetSlot(instant, EPOCHNANOSECONDS), timeZoneRecord.object, calendarRecord.object); } withTimeZone(timeZone) { if (!ES.IsTemporalZonedDateTime(this)) throw new TypeError('invalid receiver'); @@ -350,7 +360,7 @@ export class ZonedDateTime { if (!ES.IsTemporalZonedDateTime(this)) throw new TypeError('invalid receiver'); calendar = ES.ToTemporalCalendar(calendar); const Construct = ES.SpeciesConstructor(this, ZonedDateTime); - const result = new Construct(GetSlot(this, EPOCHNANOSECONDS), GetSlot(this, TIME_ZONE), calendar); + const result = new Construct(GetSlot(this, EPOCHNANOSECONDS), GetSlot(this, TIME_ZONE_RECORD).object, calendar); if (!ES.IsTemporalZonedDateTime(result)) throw new TypeError('invalid result'); return result; } @@ -360,11 +370,11 @@ export class ZonedDateTime { const { years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds } = duration; ES.RejectDurationSign(years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds); options = ES.NormalizeOptionsObject(options); - const timeZone = GetSlot(this, TIME_ZONE); + const timeZoneRecord = GetSlot(this, TIME_ZONE_RECORD); const calendarRecord = GetSlot(this, CALENDAR_RECORD); const epochNanoseconds = ES.AddZonedDateTime( GetSlot(this, INSTANT), - timeZone, + timeZoneRecord, calendarRecord, years, months, @@ -379,7 +389,7 @@ export class ZonedDateTime { options ); const Construct = ES.SpeciesConstructor(this, ZonedDateTime); - const result = new Construct(epochNanoseconds, timeZone, calendarRecord.object); + const result = new Construct(epochNanoseconds, timeZoneRecord.object, calendarRecord.object); if (!ES.IsTemporalZonedDateTime(result)) throw new TypeError('invalid result'); return result; } @@ -389,11 +399,11 @@ export class ZonedDateTime { const { years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds } = duration; ES.RejectDurationSign(years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds); options = ES.NormalizeOptionsObject(options); - const timeZone = GetSlot(this, TIME_ZONE); + const timeZoneRecord = GetSlot(this, TIME_ZONE_RECORD); const calendarRecord = GetSlot(this, CALENDAR_RECORD); const epochNanoseconds = ES.AddZonedDateTime( GetSlot(this, INSTANT), - timeZone, + timeZoneRecord, calendarRecord, -years, -months, @@ -408,7 +418,7 @@ export class ZonedDateTime { options ); const Construct = ES.SpeciesConstructor(this, ZonedDateTime); - const result = new Construct(epochNanoseconds, timeZone, calendarRecord.object); + const result = new Construct(epochNanoseconds, timeZoneRecord.object, calendarRecord.object); if (!ES.IsTemporalZonedDateTime(result)) throw new TypeError('invalid result'); return result; } @@ -457,8 +467,8 @@ export class ZonedDateTime { largestUnit )); } else { - const timeZone = GetSlot(this, TIME_ZONE); - if (!ES.TimeZoneEquals(timeZone, GetSlot(other, TIME_ZONE))) { + const timeZoneRecord = GetSlot(this, TIME_ZONE_RECORD); + if (!ES.TimeZoneEquals(timeZoneRecord, GetSlot(other, TIME_ZONE_RECORD))) { throw new RangeError( "When calculating difference between time zones, largestUnit must be 'hours' " + 'or smaller because day lengths can vary between time zones due to DST or time zone offset changes.' @@ -476,7 +486,7 @@ export class ZonedDateTime { milliseconds, microseconds, nanoseconds - } = ES.DifferenceZonedDateTime(ns1, ns2, timeZone, calendarRecord, largestUnit, untilOptions)); + } = ES.DifferenceZonedDateTime(ns1, ns2, timeZoneRecord, calendarRecord, largestUnit, untilOptions)); ({ years, months, @@ -582,8 +592,8 @@ export class ZonedDateTime { largestUnit )); } else { - const timeZone = GetSlot(this, TIME_ZONE); - if (!ES.TimeZoneEquals(timeZone, GetSlot(other, TIME_ZONE))) { + const timeZoneRecord = GetSlot(this, TIME_ZONE_RECORD); + if (!ES.TimeZoneEquals(timeZoneRecord, GetSlot(other, TIME_ZONE_RECORD))) { throw new RangeError( "When calculating difference between time zones, largestUnit must be 'hours' " + 'or smaller because day lengths can vary between time zones due to DST or time zone offset changes.' @@ -601,7 +611,7 @@ export class ZonedDateTime { milliseconds, microseconds, nanoseconds - } = ES.DifferenceZonedDateTime(ns1, ns2, timeZone, calendarRecord, largestUnit, untilOptions)); + } = ES.DifferenceZonedDateTime(ns1, ns2, timeZoneRecord, calendarRecord, largestUnit, untilOptions)); ({ years, months, @@ -702,11 +712,11 @@ export class ZonedDateTime { let nanosecond = GetSlot(dt, ISO_NANOSECOND); const DateTime = GetIntrinsic('%Temporal.PlainDateTime%'); - const timeZone = GetSlot(this, TIME_ZONE); + const timeZoneRecord = GetSlot(this, TIME_ZONE_RECORD); const calendarRecord = GetSlot(this, CALENDAR_RECORD); const dtStart = new DateTime(GetSlot(dt, ISO_YEAR), GetSlot(dt, ISO_MONTH), GetSlot(dt, ISO_DAY), 0, 0, 0, 0, 0, 0); - const instantStart = ES.BuiltinTimeZoneGetInstantFor(timeZone, dtStart, 'compatible'); - const endNs = ES.AddZonedDateTime(instantStart, timeZone, calendarRecord, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0); + const instantStart = ES.BuiltinTimeZoneGetInstantFor(timeZoneRecord, dtStart, 'compatible'); + const endNs = ES.AddZonedDateTime(instantStart, timeZoneRecord, calendarRecord, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0); const dayLengthNs = endNs.subtract(GetSlot(instantStart, EPOCHNANOSECONDS)); ({ year, month, day, hour, minute, second, millisecond, microsecond, nanosecond } = ES.RoundISODateTime( year, @@ -729,7 +739,7 @@ export class ZonedDateTime { // offset. Otherwise the offset will be changed to be compatible with the // new date/time values. If DST disambiguation is required, the `compatible` // disambiguation algorithm will be used. - const offsetNs = ES.GetOffsetNanosecondsFor(timeZone, GetSlot(this, INSTANT)); + const offsetNs = ES.GetOffsetNanosecondsFor(timeZoneRecord, GetSlot(this, INSTANT)); const epochNanoseconds = ES.InterpretISODateTimeOffset( year, month, @@ -741,13 +751,13 @@ export class ZonedDateTime { microsecond, nanosecond, offsetNs, - timeZone, + timeZoneRecord, 'compatible', 'prefer' ); const Construct = ES.SpeciesConstructor(this, ZonedDateTime); - const result = new Construct(epochNanoseconds, timeZone, calendarRecord.object); + const result = new Construct(epochNanoseconds, timeZoneRecord.object, calendarRecord.object); if (!ES.IsTemporalZonedDateTime(result)) throw new TypeError('invalid result'); return result; } @@ -757,7 +767,7 @@ export class ZonedDateTime { const one = GetSlot(this, EPOCHNANOSECONDS); const two = GetSlot(other, EPOCHNANOSECONDS); if (!bigInt(one).equals(two)) return false; - if (!ES.TimeZoneEquals(GetSlot(this, TIME_ZONE), GetSlot(other, TIME_ZONE))) return false; + if (!ES.TimeZoneEquals(GetSlot(this, TIME_ZONE_RECORD), GetSlot(other, TIME_ZONE_RECORD))) return false; return ES.CalendarEquals(GetSlot(this, CALENDAR_RECORD), GetSlot(other, CALENDAR_RECORD)); } toString(options = undefined) { @@ -790,10 +800,14 @@ export class ZonedDateTime { const dt = dateTime(this); const DateTime = GetIntrinsic('%Temporal.PlainDateTime%'); const dtStart = new DateTime(GetSlot(dt, ISO_YEAR), GetSlot(dt, ISO_MONTH), GetSlot(dt, ISO_DAY), 0, 0, 0, 0, 0, 0); - const timeZone = GetSlot(this, TIME_ZONE); - const instant = ES.BuiltinTimeZoneGetInstantFor(timeZone, dtStart, 'compatible'); + const timeZoneRecord = GetSlot(this, TIME_ZONE_RECORD); + const instant = ES.BuiltinTimeZoneGetInstantFor(timeZoneRecord, dtStart, 'compatible'); const Construct = ES.SpeciesConstructor(this, ZonedDateTime); - const result = new Construct(GetSlot(instant, EPOCHNANOSECONDS), timeZone, GetSlot(this, CALENDAR_RECORD).object); + const result = new Construct( + GetSlot(instant, EPOCHNANOSECONDS), + timeZoneRecord.object, + GetSlot(this, CALENDAR_RECORD).object + ); if (!ES.IsTemporalZonedDateTime(result)) throw new TypeError('invalid result'); return result; } @@ -833,7 +847,7 @@ export class ZonedDateTime { getISOFields() { if (!ES.IsTemporalZonedDateTime(this)) throw new TypeError('invalid receiver'); const dt = dateTime(this); - const tz = GetSlot(this, TIME_ZONE); + const timeZoneRecord = GetSlot(this, TIME_ZONE_RECORD); return { calendar: GetSlot(this, CALENDAR_RECORD).object, isoDay: GetSlot(dt, ISO_DAY), @@ -845,8 +859,8 @@ export class ZonedDateTime { isoNanosecond: GetSlot(dt, ISO_NANOSECOND), isoSecond: GetSlot(dt, ISO_SECOND), isoYear: GetSlot(dt, ISO_YEAR), - offset: ES.BuiltinTimeZoneGetOffsetStringFor(tz, GetSlot(this, INSTANT)), - timeZone: tz + offset: ES.BuiltinTimeZoneGetOffsetStringFor(timeZoneRecord, GetSlot(this, INSTANT)), + timeZone: timeZoneRecord.object }; } static from(item, options = undefined) { @@ -857,7 +871,7 @@ export class ZonedDateTime { ES.ToTemporalOffset(options, 'reject'); const result = new this( GetSlot(item, EPOCHNANOSECONDS), - GetSlot(item, TIME_ZONE), + GetSlot(item, TIME_ZONE_RECORD).object, GetSlot(item, CALENDAR_RECORD).object ); if (!ES.IsTemporalZonedDateTime(result)) throw new TypeError('invalid result'); @@ -874,7 +888,7 @@ export class ZonedDateTime { if (bigInt(ns1).greater(ns2)) return 1; const calendarResult = ES.CalendarCompare(GetSlot(one, CALENDAR_RECORD), GetSlot(two, CALENDAR_RECORD)); if (calendarResult) return calendarResult; - return ES.TimeZoneCompare(GetSlot(one, TIME_ZONE), GetSlot(two, TIME_ZONE)); + return ES.TimeZoneCompare(GetSlot(one, TIME_ZONE_RECORD), GetSlot(two, TIME_ZONE_RECORD)); } } @@ -886,7 +900,7 @@ function bigIntIfAvailable(wrapper) { function dateTime(zdt) { return ES.BuiltinTimeZoneGetPlainDateTimeFor( - GetSlot(zdt, TIME_ZONE), + GetSlot(zdt, TIME_ZONE_RECORD), GetSlot(zdt, INSTANT), GetSlot(zdt, CALENDAR_RECORD) ); @@ -909,9 +923,9 @@ function zonedDateTimeToString( instant = new TemporalInstant(ns); } - const tz = GetSlot(zdt, TIME_ZONE); + const timeZoneRecord = GetSlot(zdt, TIME_ZONE_RECORD); const iso = ES.NewCalendarRecord(ES.GetISO8601Calendar()); - const dateTime = ES.BuiltinTimeZoneGetPlainDateTimeFor(tz, instant, iso); + const dateTime = ES.BuiltinTimeZoneGetPlainDateTimeFor(timeZoneRecord, instant, iso); const year = ES.ISOYearString(GetSlot(dateTime, ISO_YEAR)); const month = ES.ISODateTimePartString(GetSlot(dateTime, ISO_MONTH)); @@ -926,8 +940,8 @@ function zonedDateTimeToString( precision ); let result = `${year}-${month}-${day}T${hour}:${minute}${seconds}`; - if (showOffset !== 'never') result += ES.BuiltinTimeZoneGetOffsetStringFor(tz, instant); - if (showTimeZone !== 'never') result += `[${tz}]`; + if (showOffset !== 'never') result += ES.BuiltinTimeZoneGetOffsetStringFor(timeZoneRecord, instant); + if (showTimeZone !== 'never') result += `[${ES.TimeZoneToString(timeZoneRecord)}]`; const calendarID = ES.CalendarToString(GetSlot(zdt, CALENDAR_RECORD)); result += ES.FormatCalendarAnnotation(calendarID, showCalendar); return result; diff --git a/polyfill/test/Instant/prototype/toString/timezone-no-tostring.js b/polyfill/test/Instant/prototype/toString/timezone-no-tostring.js deleted file mode 100644 index edefd5b9a6..0000000000 --- a/polyfill/test/Instant/prototype/toString/timezone-no-tostring.js +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (C) 2020 Igalia, S.L. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-temporal.instant.prototype.tostring -includes: [compareArray.js] ----*/ - -const actual = []; -const expected = []; - -const instant = Temporal.Instant.from("1975-02-02T14:25:36.123456789+02:00"); -const timeZone = new Temporal.TimeZone("UTC"); -Object.defineProperty(timeZone, "toString", { - get() { - actual.push("get timeZone.toString"); - return undefined; - }, -}); - -Object.defineProperty(Temporal.TimeZone, "from", { - get() { - actual.push("get Temporal.TimeZone.from"); - return undefined; - }, -}); - -assert.sameValue(instant.toString({ timeZone }), "1975-02-02T12:25:36.123456789+00:00"); -assert.compareArray(actual, expected); diff --git a/polyfill/test/Instant/prototype/toString/timezone.js b/polyfill/test/Instant/prototype/toString/timezone.js index 805818ac76..e7aa3e9350 100644 --- a/polyfill/test/Instant/prototype/toString/timezone.js +++ b/polyfill/test/Instant/prototype/toString/timezone.js @@ -3,19 +3,20 @@ /*--- esid: sec-temporal.instant.prototype.tostring -includes: [compareArray.js] +includes: [compareArray.js, temporalHelpers.js] ---*/ const actual = []; const expected = [ "get timeZone.getOffsetNanosecondsFor", + "get timeZone.getPossibleInstantsFor", + "get timeZone.toString", "call timeZone.getOffsetNanosecondsFor", - "get timeZone.getOffsetNanosecondsFor", "call timeZone.getOffsetNanosecondsFor", ]; const instant = Temporal.Instant.from("1975-02-02T14:25:36.123456Z"); -const timeZone = new Proxy({ +const timeZone = new Proxy(Object.assign({}, MINIMAL_TIME_ZONE_OBJECT, { name: "Custom/TimeZone", toString() { @@ -36,7 +37,7 @@ const timeZone = new Proxy({ assert.sameValue(instantArg.epochNanoseconds, instant.epochNanoseconds); return -8735135801679; }, -}, { +}), { has(target, property) { actual.push(`has timeZone.${property}`); return property in target; diff --git a/polyfill/test/Instant/prototype/toZonedDateTime/calendar-from-undefined.js b/polyfill/test/Instant/prototype/toZonedDateTime/calendar-from-undefined.js index 4dba2adfe8..21f81d7ffd 100644 --- a/polyfill/test/Instant/prototype/toZonedDateTime/calendar-from-undefined.js +++ b/polyfill/test/Instant/prototype/toZonedDateTime/calendar-from-undefined.js @@ -3,23 +3,26 @@ /*--- esid: sec-temporal.instant.prototype.tozoneddatetime -includes: [compareArray.js] +includes: [compareArray.js, temporalHelpers.js] ---*/ const actual = []; const expected = [ "get Temporal.Calendar.from", + "get timeZone.getOffsetNanosecondsFor", + "get timeZone.getPossibleInstantsFor", + "get timeZone.toString", ]; const instant = Temporal.Instant.from("1975-02-02T14:25:36.123456789Z"); const dateTime = Temporal.PlainDateTime.from("1963-07-02T12:34:56.987654321"); -const timeZone = new Proxy({ +const timeZone = new Proxy(Object.assign({}, MINIMAL_TIME_ZONE_OBJECT, { getPlainDateTimeFor() { actual.push("call timeZone.getPlainDateTimeFor"); return dateTime; }, -}, { +}), { has(target, property) { actual.push(`has timeZone.${property}`); return property in target; diff --git a/polyfill/test/Instant/prototype/toZonedDateTime/calendar-function.js b/polyfill/test/Instant/prototype/toZonedDateTime/calendar-function.js index e64705d1e7..d87ab229b2 100644 --- a/polyfill/test/Instant/prototype/toZonedDateTime/calendar-function.js +++ b/polyfill/test/Instant/prototype/toZonedDateTime/calendar-function.js @@ -7,17 +7,21 @@ includes: [compareArray.js, temporalHelpers.js] ---*/ const actual = []; -const expected = []; +const expected = [ + "get timeZone.getOffsetNanosecondsFor", + "get timeZone.getPossibleInstantsFor", + "get timeZone.toString", +]; const instant = Temporal.Instant.from("1975-02-02T14:25:36.123456789Z"); const dateTime = Temporal.PlainDateTime.from("1963-07-02T12:34:56.987654321"); const calendar = Object.assign(function () {}, MINIMAL_CALENDAR_OBJECT); -const timeZone = new Proxy({ +const timeZone = new Proxy(Object.assign({}, MINIMAL_TIME_ZONE_OBJECT, { getPlainDateTimeFor() { actual.push("call timeZone.getPlainDateTimeFor"); return dateTime; }, -}, { +}), { has(target, property) { actual.push(`has timeZone.${property}`); return property in target; diff --git a/polyfill/test/Instant/prototype/toZonedDateTime/calendar-object.js b/polyfill/test/Instant/prototype/toZonedDateTime/calendar-object.js index b8275d1796..5a5468dd4e 100644 --- a/polyfill/test/Instant/prototype/toZonedDateTime/calendar-object.js +++ b/polyfill/test/Instant/prototype/toZonedDateTime/calendar-object.js @@ -7,17 +7,21 @@ includes: [compareArray.js, temporalHelpers.js] ---*/ const actual = []; -const expected = []; +const expected = [ + "get timeZone.getOffsetNanosecondsFor", + "get timeZone.getPossibleInstantsFor", + "get timeZone.toString", +]; const instant = Temporal.Instant.from("1975-02-02T14:25:36.123456789Z"); const dateTime = Temporal.PlainDateTime.from("1963-07-02T12:34:56.987654321"); const calendar = MINIMAL_CALENDAR_OBJECT; -const timeZone = new Proxy({ +const timeZone = new Proxy(Object.assign({}, MINIMAL_TIME_ZONE_OBJECT, { getPlainDateTimeFor() { actual.push("call timeZone.getPlainDateTimeFor"); return dateTime; }, -}, { +}), { has(target, property) { actual.push(`has timeZone.${property}`); return property in target; diff --git a/polyfill/test/Instant/prototype/toZonedDateTime/calendar.js b/polyfill/test/Instant/prototype/toZonedDateTime/calendar.js index 2403f09ffd..a816bd29fb 100644 --- a/polyfill/test/Instant/prototype/toZonedDateTime/calendar.js +++ b/polyfill/test/Instant/prototype/toZonedDateTime/calendar.js @@ -12,6 +12,9 @@ const expected = [ "call Temporal.Calendar.from", "get Temporal.TimeZone.from", "call Temporal.TimeZone.from", + "get timeZone.getOffsetNanosecondsFor", + "get timeZone.getPossibleInstantsFor", + "get timeZone.toString", ]; const instant = Temporal.Instant.from("1975-02-02T14:25:36.123456789Z"); @@ -19,12 +22,12 @@ const dateTime = Temporal.PlainDateTime.from("1963-07-02T12:34:56.987654321"); const calendar = MINIMAL_CALENDAR_OBJECT; -const timeZone = new Proxy({ +const timeZone = new Proxy(Object.assign({}, MINIMAL_TIME_ZONE_OBJECT, { getPlainDateTimeFor() { actual.push("call timeZone.getPlainDateTimeFor"); return dateTime; }, -}, { +}), { has(target, property) { actual.push(`has timeZone.${property}`); return property in target; diff --git a/polyfill/test/Instant/prototype/toZonedDateTime/plain-custom-timezone.js b/polyfill/test/Instant/prototype/toZonedDateTime/plain-custom-timezone.js index 2a887ade78..f6c9537af8 100644 --- a/polyfill/test/Instant/prototype/toZonedDateTime/plain-custom-timezone.js +++ b/polyfill/test/Instant/prototype/toZonedDateTime/plain-custom-timezone.js @@ -3,21 +3,25 @@ /*--- esid: sec-temporal.instant.prototype.tozoneddatetime -includes: [compareArray.js] +includes: [compareArray.js, temporalHelpers.js] ---*/ const actual = []; -const expected = []; +const expected = [ + "get timeZone.getOffsetNanosecondsFor", + "get timeZone.getPossibleInstantsFor", + "get timeZone.toString", +]; const instant = Temporal.Instant.from("1975-02-02T14:25:36.123456789Z"); const dateTime = Temporal.PlainDateTime.from("1963-07-02T12:00:00.987654321"); const calendar = Temporal.Calendar.from("iso8601"); -const timeZone = new Proxy({ +const timeZone = new Proxy(Object.assign({}, MINIMAL_TIME_ZONE_OBJECT, { getPlainDateTimeFor() { actual.push("call timeZone.getPlainDateTimeFor"); return dateTime; } -}, { +}), { has(target, property) { actual.push(`has timeZone.${property}`); return property in target; diff --git a/polyfill/test/PlainDateTime/prototype/toZonedDateTime/plain-custom-timezone.js b/polyfill/test/PlainDateTime/prototype/toZonedDateTime/plain-custom-timezone.js index ff594df7a8..80250bf3aa 100644 --- a/polyfill/test/PlainDateTime/prototype/toZonedDateTime/plain-custom-timezone.js +++ b/polyfill/test/PlainDateTime/prototype/toZonedDateTime/plain-custom-timezone.js @@ -3,15 +3,17 @@ /*--- esid: sec-temporal.plaindatetime.prototype.tozoneddatetime -includes: [compareArray.js] +includes: [compareArray.js, temporalHelpers.js] ---*/ const actual = []; const expected = [ + "get timeZone.getOffsetNanosecondsFor", + "get timeZone.getPossibleInstantsFor", + "get timeZone.toString", "get options.disambiguation", "get disambiguation.toString", "call disambiguation.toString", - "get timeZone.getPossibleInstantsFor", "call timeZone.getPossibleInstantsFor", ]; @@ -46,13 +48,13 @@ const options = new Proxy({ }, }); -const timeZone = new Proxy({ +const timeZone = new Proxy(Object.assign({}, MINIMAL_TIME_ZONE_OBJECT, { getPossibleInstantsFor(dateTimeArg) { actual.push("call timeZone.getPossibleInstantsFor"); assert.sameValue(dateTimeArg, dateTime); return [instant]; }, -}, { +}), { has(target, property) { actual.push(`has timeZone.${property}`); return property in target; diff --git a/polyfill/test/TimeZone/prototype/getOffsetStringFor/custom-timezone.js b/polyfill/test/TimeZone/prototype/getOffsetStringFor/custom-timezone.js index dfc8f8a491..dfc858c71a 100644 --- a/polyfill/test/TimeZone/prototype/getOffsetStringFor/custom-timezone.js +++ b/polyfill/test/TimeZone/prototype/getOffsetStringFor/custom-timezone.js @@ -3,23 +3,25 @@ /*--- esid: sec-temporal.timezone.prototype.getoffsetstringfor -includes: [compareArray.js] +includes: [compareArray.js, temporalHelpers.js] ---*/ const actual = []; const expected = [ "get timeZone.getOffsetNanosecondsFor", + "get timeZone.getPossibleInstantsFor", + "get timeZone.toString", "call timeZone.getOffsetNanosecondsFor", ]; const instant = Temporal.Instant.from("1975-02-02T14:25:36.123456789Z"); -const timeZone = new Proxy({ +const timeZone = new Proxy(Object.assign({}, MINIMAL_TIME_ZONE_OBJECT, { getOffsetNanosecondsFor(instantArg) { actual.push("call timeZone.getOffsetNanosecondsFor"); assert.sameValue(instantArg, instant); return 9876543210123; }, -}, { +}), { has(target, property) { actual.push(`has timeZone.${property}`); return property in target; diff --git a/polyfill/test/TimeZone/prototype/getOffsetStringFor/getOffsetNanosecondsFor-undefined.js b/polyfill/test/TimeZone/prototype/getOffsetStringFor/getOffsetNanosecondsFor-undefined.js deleted file mode 100644 index f873dc6b2f..0000000000 --- a/polyfill/test/TimeZone/prototype/getOffsetStringFor/getOffsetNanosecondsFor-undefined.js +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (C) 2020 Igalia, S.L. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-temporal.timezone.prototype.getoffsetstringfor ----*/ - -const instant = Temporal.Instant.from("1975-02-02T14:25:36.123456789Z"); -const timeZone = Temporal.TimeZone.from("Europe/Madrid"); -timeZone.getOffsetNanosecondsFor = undefined; -assert.sameValue(timeZone.getOffsetStringFor(instant), "+01:00"); diff --git a/polyfill/test/TimeZone/prototype/getPlainDateTimeFor/calendar-function.js b/polyfill/test/TimeZone/prototype/getPlainDateTimeFor/calendar-function.js index f229021523..6ab01d901c 100644 --- a/polyfill/test/TimeZone/prototype/getPlainDateTimeFor/calendar-function.js +++ b/polyfill/test/TimeZone/prototype/getPlainDateTimeFor/calendar-function.js @@ -9,18 +9,20 @@ includes: [compareArray.js, temporalHelpers.js] const actual = []; const expected = [ "get timeZone.getOffsetNanosecondsFor", + "get timeZone.getPossibleInstantsFor", + "get timeZone.toString", "call timeZone.getOffsetNanosecondsFor", ]; const instant = Temporal.Instant.from("1975-02-02T14:25:36.123456789Z"); const calendar = Object.assign(function() {}, MINIMAL_CALENDAR_OBJECT); -const timeZone = new Proxy({ +const timeZone = new Proxy(Object.assign({}, MINIMAL_TIME_ZONE_OBJECT, { getOffsetNanosecondsFor(instantArg) { actual.push("call timeZone.getOffsetNanosecondsFor"); assert.sameValue(instantArg, instant); return 72e11; }, -}, { +}), { has(target, property) { actual.push(`has timeZone.${property}`); return property in target; diff --git a/polyfill/test/TimeZone/prototype/getPlainDateTimeFor/calendar-object.js b/polyfill/test/TimeZone/prototype/getPlainDateTimeFor/calendar-object.js index 011845ca78..1c76bfe725 100644 --- a/polyfill/test/TimeZone/prototype/getPlainDateTimeFor/calendar-object.js +++ b/polyfill/test/TimeZone/prototype/getPlainDateTimeFor/calendar-object.js @@ -9,18 +9,20 @@ includes: [compareArray.js, temporalHelpers.js] const actual = []; const expected = [ "get timeZone.getOffsetNanosecondsFor", + "get timeZone.getPossibleInstantsFor", + "get timeZone.toString", "call timeZone.getOffsetNanosecondsFor", ]; const instant = Temporal.Instant.from("1975-02-02T14:25:36.123456789Z"); const calendar = MINIMAL_CALENDAR_OBJECT; -const timeZone = new Proxy({ +const timeZone = new Proxy(Object.assign({}, MINIMAL_TIME_ZONE_OBJECT, { getOffsetNanosecondsFor(instantArg) { actual.push("call timeZone.getOffsetNanosecondsFor"); assert.sameValue(instantArg, instant); return 72e11; }, -}, { +}), { has(target, property) { actual.push(`has timeZone.${property}`); return property in target; diff --git a/polyfill/test/TimeZone/prototype/getPlainDateTimeFor/custom-timezone.js b/polyfill/test/TimeZone/prototype/getPlainDateTimeFor/custom-timezone.js index 0e42597068..21fb8f85e0 100644 --- a/polyfill/test/TimeZone/prototype/getPlainDateTimeFor/custom-timezone.js +++ b/polyfill/test/TimeZone/prototype/getPlainDateTimeFor/custom-timezone.js @@ -3,23 +3,25 @@ /*--- esid: sec-temporal.timezone.prototype.getplaindatetimefor -includes: [compareArray.js] +includes: [compareArray.js, temporalHelpers.js] ---*/ const actual = []; const expected = [ "get timeZone.getOffsetNanosecondsFor", + "get timeZone.getPossibleInstantsFor", + "get timeZone.toString", "call timeZone.getOffsetNanosecondsFor", ]; const instant = Temporal.Instant.from("1975-02-02T14:25:36.123456789Z"); -const timeZone = new Proxy({ +const timeZone = new Proxy(Object.assign({}, MINIMAL_TIME_ZONE_OBJECT, { getOffsetNanosecondsFor(instantArg) { actual.push("call timeZone.getOffsetNanosecondsFor"); assert.sameValue(instantArg, instant); return 9876543210123; }, -}, { +}), { has(target, property) { actual.push(`has timeZone.${property}`); return property in target; diff --git a/polyfill/test/TimeZone/prototype/getPlainDateTimeFor/getOffsetNanosecondsFor-undefined.js b/polyfill/test/TimeZone/prototype/getPlainDateTimeFor/getOffsetNanosecondsFor-undefined.js deleted file mode 100644 index b4d3eb382c..0000000000 --- a/polyfill/test/TimeZone/prototype/getPlainDateTimeFor/getOffsetNanosecondsFor-undefined.js +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (C) 2020 Igalia, S.L. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-temporal.timezone.prototype.getplaindatetimefor ----*/ - -const instant = Temporal.Instant.from("1975-02-02T14:25:36.123456789Z"); -const timeZone = Temporal.TimeZone.from("Europe/Madrid"); -timeZone.getOffsetNanosecondsFor = undefined; -const result = timeZone.getPlainDateTimeFor(instant); -assert.sameValue(result.year, 1975); -assert.sameValue(result.month, 2); -assert.sameValue(result.day, 2); -assert.sameValue(result.hour, 15); -assert.sameValue(result.minute, 25); -assert.sameValue(result.second, 36); -assert.sameValue(result.millisecond, 123); -assert.sameValue(result.microsecond, 456); -assert.sameValue(result.nanosecond, 789); -assert.sameValue(result.toString(), "1975-02-02T15:25:36.123456789"); diff --git a/polyfill/test/ZonedDateTime/constructor/constructor/timezone-undefined.js b/polyfill/test/ZonedDateTime/constructor/constructor/timezone-undefined.js index 0cb73855e1..36798b8ed7 100644 --- a/polyfill/test/ZonedDateTime/constructor/constructor/timezone-undefined.js +++ b/polyfill/test/ZonedDateTime/constructor/constructor/timezone-undefined.js @@ -3,7 +3,7 @@ /*--- esid: sec-temporal.zoneddatetime -includes: [compareArray.js] +includes: [compareArray.js, temporalHelpers.js] features: [BigInt] ---*/ @@ -13,7 +13,7 @@ const expected = [ ]; let actual; const argument = 957270896987654321n; -const timeZone = {}; +const timeZone = MINIMAL_TIME_ZONE_OBJECT; Object.defineProperty(Temporal.TimeZone, "from", { get() { diff --git a/polyfill/test/ZonedDateTime/prototype/toPlainDateTime/plain-custom-timezone.js b/polyfill/test/ZonedDateTime/prototype/toPlainDateTime/plain-custom-timezone.js index 30b8298496..7795b74354 100644 --- a/polyfill/test/ZonedDateTime/prototype/toPlainDateTime/plain-custom-timezone.js +++ b/polyfill/test/ZonedDateTime/prototype/toPlainDateTime/plain-custom-timezone.js @@ -3,21 +3,23 @@ /*--- esid: sec-temporal.zoneddatetime.prototype.toplaindatetime -includes: [compareArray.js] +includes: [compareArray.js, temporalHelpers.js] ---*/ const actual = []; const expected = [ "get timeZone.getOffsetNanosecondsFor", + "get timeZone.getPossibleInstantsFor", + "get timeZone.toString", "call timeZone.getOffsetNanosecondsFor", ]; -const timeZone = new Proxy({ +const timeZone = new Proxy(Object.assign({}, MINIMAL_TIME_ZONE_OBJECT, { getOffsetNanosecondsFor() { actual.push("call timeZone.getOffsetNanosecondsFor"); return -8735135802468; }, -}, { +}), { has(target, property) { actual.push(`has timeZone.${property}`); return property in target; diff --git a/polyfill/test/ZonedDateTime/prototype/toPlainDateTime/timezone-invalid-result.js b/polyfill/test/ZonedDateTime/prototype/toPlainDateTime/timezone-invalid-result.js index 0cb688a966..456fd396a1 100644 --- a/polyfill/test/ZonedDateTime/prototype/toPlainDateTime/timezone-invalid-result.js +++ b/polyfill/test/ZonedDateTime/prototype/toPlainDateTime/timezone-invalid-result.js @@ -3,6 +3,7 @@ /*--- esid: sec-temporal.zoneddatetime.prototype.toplaindatetime +includes: [temporalHelpers.js] ---*/ const calendar = Temporal.Calendar.from("iso8601"); @@ -13,22 +14,19 @@ const invalidValues = [ true, "2020-01-01T12:45:36", Symbol(), - 2020, 2n, {}, Temporal.PlainDateTime, Temporal.PlainDateTime.prototype, ]; -for (const dateTime of invalidValues) { - const timeZone = { - getPlainDateTimeFor(instantArg, calendarArg) { +for (const offset of invalidValues) { + const timeZone = Object.assign({}, MINIMAL_TIME_ZONE_OBJECT, { + getOffsetNanosecondsFor(instantArg) { assert.sameValue(instantArg instanceof Temporal.Instant, true, "Instant"); - assert.sameValue(calendarArg instanceof Temporal.Calendar, true, "Calendar"); - assert.sameValue(calendarArg, calendar); - return dateTime; + return offset; }, - }; + }); const zdt = new Temporal.ZonedDateTime(160583136123456789n, timeZone, calendar); assert.throws(TypeError, () => zdt.toPlainDateTime(timeZone, calendar)); diff --git a/polyfill/test/helpers/temporalHelpers.js b/polyfill/test/helpers/temporalHelpers.js index 062c5dae1f..e31cc9da3e 100644 --- a/polyfill/test/helpers/temporalHelpers.js +++ b/polyfill/test/helpers/temporalHelpers.js @@ -3,7 +3,7 @@ /*--- description: | This defines helper objects and functions for testing Temporal. -defines: [MINIMAL_CALENDAR_OBJECT] +defines: [MINIMAL_CALENDAR_OBJECT, MINIMAL_TIME_ZONE_OBJECT] ---*/ /* eslint no-unused-vars: "off", @typescript-eslint/no-unused-vars: "off" */ @@ -30,3 +30,9 @@ var MINIMAL_CALENDAR_OBJECT = { inLeapYear() { return undefined; }, toString() { throw new Error('not implemented'); }, }; + +var MINIMAL_TIME_ZONE_OBJECT = { + getOffsetNanosecondsFor() { throw new Error('not implemented'); }, + getPossibleInstantsFor() { throw new Error('not implemented'); }, + toString() { throw new Error('not implemented'); }, +}; diff --git a/polyfill/test/now/plainDate/calendar-from-undefined.js b/polyfill/test/now/plainDate/calendar-from-undefined.js index e60a22b606..76ff9b5c01 100644 --- a/polyfill/test/now/plainDate/calendar-from-undefined.js +++ b/polyfill/test/now/plainDate/calendar-from-undefined.js @@ -3,23 +3,25 @@ /*--- esid: sec-temporal.now.plaindate -includes: [compareArray.js] +includes: [compareArray.js, temporalHelpers.js] ---*/ const actual = []; const expected = [ - "get Temporal.Calendar.from", "get timeZone.getOffsetNanosecondsFor", + "get timeZone.getPossibleInstantsFor", + "get timeZone.toString", + "get Temporal.Calendar.from", "call timeZone.getOffsetNanosecondsFor", ]; -const timeZone = new Proxy({ +const timeZone = new Proxy(Object.assign({}, MINIMAL_TIME_ZONE_OBJECT, { getOffsetNanosecondsFor(instant) { actual.push("call timeZone.getOffsetNanosecondsFor"); assert.sameValue(instant instanceof Temporal.Instant, true, "Instant"); return 86399_999_999_999; }, -}, { +}), { has(target, property) { actual.push(`has timeZone.${property}`); return property in target; diff --git a/polyfill/test/now/plainDate/calendar-function.js b/polyfill/test/now/plainDate/calendar-function.js index 79eab13de0..5af5b179af 100644 --- a/polyfill/test/now/plainDate/calendar-function.js +++ b/polyfill/test/now/plainDate/calendar-function.js @@ -9,17 +9,19 @@ includes: [compareArray.js, temporalHelpers.js] const actual = []; const expected = [ "get timeZone.getOffsetNanosecondsFor", + "get timeZone.getPossibleInstantsFor", + "get timeZone.toString", "call timeZone.getOffsetNanosecondsFor", ]; const calendar = Object.assign(function() {}, MINIMAL_CALENDAR_OBJECT); -const timeZone = new Proxy({ +const timeZone = new Proxy(Object.assign({}, MINIMAL_TIME_ZONE_OBJECT, { getOffsetNanosecondsFor(instant) { actual.push("call timeZone.getOffsetNanosecondsFor"); assert.sameValue(instant instanceof Temporal.Instant, true, "Instant"); return 86399_999_999_999; }, -}, { +}), { has(target, property) { actual.push(`has timeZone.${property}`); return property in target; diff --git a/polyfill/test/now/plainDate/calendar-object.js b/polyfill/test/now/plainDate/calendar-object.js index aff172b06d..aec77ce556 100644 --- a/polyfill/test/now/plainDate/calendar-object.js +++ b/polyfill/test/now/plainDate/calendar-object.js @@ -9,17 +9,19 @@ includes: [compareArray.js, temporalHelpers.js] const actual = []; const expected = [ "get timeZone.getOffsetNanosecondsFor", + "get timeZone.getPossibleInstantsFor", + "get timeZone.toString", "call timeZone.getOffsetNanosecondsFor", ]; const calendar = MINIMAL_CALENDAR_OBJECT; -const timeZone = new Proxy({ +const timeZone = new Proxy(Object.assign({}, MINIMAL_TIME_ZONE_OBJECT, { getOffsetNanosecondsFor(instant) { actual.push("call timeZone.getOffsetNanosecondsFor"); assert.sameValue(instant instanceof Temporal.Instant, true, "Instant"); return 86399_999_999_999; }, -}, { +}), { has(target, property) { actual.push(`has timeZone.${property}`); return property in target; diff --git a/polyfill/test/now/plainDate/calendar.js b/polyfill/test/now/plainDate/calendar.js index 34ee29e177..1e50217c19 100644 --- a/polyfill/test/now/plainDate/calendar.js +++ b/polyfill/test/now/plainDate/calendar.js @@ -10,21 +10,23 @@ const actual = []; const expected = [ "get Temporal.TimeZone.from", "call Temporal.TimeZone.from", + "get timeZone.getOffsetNanosecondsFor", + "get timeZone.getPossibleInstantsFor", + "get timeZone.toString", "get Temporal.Calendar.from", "call Temporal.Calendar.from", - "get timeZone.getOffsetNanosecondsFor", "call timeZone.getOffsetNanosecondsFor", ]; const calendar = MINIMAL_CALENDAR_OBJECT; -const timeZone = new Proxy({ +const timeZone = new Proxy(Object.assign({}, MINIMAL_TIME_ZONE_OBJECT, { getOffsetNanosecondsFor(instant) { actual.push("call timeZone.getOffsetNanosecondsFor"); assert.sameValue(instant instanceof Temporal.Instant, true, "Instant"); return 86399_999_999_999; }, -}, { +}), { has(target, property) { actual.push(`has timeZone.${property}`); return property in target; diff --git a/polyfill/test/now/plainDate/timezone-object.js b/polyfill/test/now/plainDate/timezone-object.js index 42384afdbf..9e42369dc8 100644 --- a/polyfill/test/now/plainDate/timezone-object.js +++ b/polyfill/test/now/plainDate/timezone-object.js @@ -3,22 +3,24 @@ /*--- esid: sec-temporal.now.plaindate -includes: [compareArray.js] +includes: [compareArray.js, temporalHelpers.js] ---*/ const actual = []; const expected = [ "get timeZone.getOffsetNanosecondsFor", + "get timeZone.getPossibleInstantsFor", + "get timeZone.toString", "call timeZone.getOffsetNanosecondsFor", ]; -const timeZone = new Proxy({ +const timeZone = new Proxy(Object.assign({}, MINIMAL_TIME_ZONE_OBJECT, { getOffsetNanosecondsFor(instant) { actual.push("call timeZone.getOffsetNanosecondsFor"); assert.sameValue(instant instanceof Temporal.Instant, true, "Instant"); return 86399_999_999_999; }, -}, { +}), { has(target, property) { actual.push(`has timeZone.${property}`); return property in target; diff --git a/polyfill/test/now/plainDate/timezone.js b/polyfill/test/now/plainDate/timezone.js index 2dda62ec42..f4d32982b0 100644 --- a/polyfill/test/now/plainDate/timezone.js +++ b/polyfill/test/now/plainDate/timezone.js @@ -3,7 +3,7 @@ /*--- esid: sec-temporal.now.plaindate -includes: [compareArray.js] +includes: [compareArray.js, temporalHelpers.js] ---*/ const actual = []; @@ -11,16 +11,18 @@ const expected = [ "get Temporal.TimeZone.from", "call Temporal.TimeZone.from", "get timeZone.getOffsetNanosecondsFor", + "get timeZone.getPossibleInstantsFor", + "get timeZone.toString", "call timeZone.getOffsetNanosecondsFor", ]; -const timeZone = new Proxy({ +const timeZone = new Proxy(Object.assign({}, MINIMAL_TIME_ZONE_OBJECT, { getOffsetNanosecondsFor(instant) { actual.push("call timeZone.getOffsetNanosecondsFor"); assert.sameValue(instant instanceof Temporal.Instant, true, "Instant"); return 86399_999_999_999; }, -}, { +}), { has(target, property) { actual.push(`has timeZone.${property}`); return property in target; diff --git a/polyfill/test/now/plainDate/toDate-override.js b/polyfill/test/now/plainDate/toDate-override.js index 7a2dc7e784..b43e6e4e48 100644 --- a/polyfill/test/now/plainDate/toDate-override.js +++ b/polyfill/test/now/plainDate/toDate-override.js @@ -3,7 +3,7 @@ /*--- esid: sec-temporal.now.plaindate -includes: [compareArray.js] +includes: [compareArray.js, temporalHelpers.js] ---*/ const actual = []; @@ -11,6 +11,8 @@ const expected = [ "get Temporal.TimeZone.from", "call Temporal.TimeZone.from", "get timeZone.getOffsetNanosecondsFor", + "get timeZone.getPossibleInstantsFor", + "get timeZone.toString", "call timeZone.getOffsetNanosecondsFor", ]; @@ -23,13 +25,13 @@ Object.defineProperty(Temporal.PlainDateTime.prototype, "toPlainDate", { }, }); -const timeZone = new Proxy({ +const timeZone = new Proxy(Object.assign({}, MINIMAL_TIME_ZONE_OBJECT, { getOffsetNanosecondsFor(instant) { actual.push("call timeZone.getOffsetNanosecondsFor"); assert.sameValue(instant instanceof Temporal.Instant, true, "Instant"); return 86399_999_999_999; }, -}, { +}), { has(target, property) { actual.push(`has timeZone.${property}`); return property in target; diff --git a/polyfill/test/now/plainDateTime/calendar-from-undefined.js b/polyfill/test/now/plainDateTime/calendar-from-undefined.js index 1dff98cf30..9060ef4089 100644 --- a/polyfill/test/now/plainDateTime/calendar-from-undefined.js +++ b/polyfill/test/now/plainDateTime/calendar-from-undefined.js @@ -3,23 +3,25 @@ /*--- esid: sec-temporal.now.plaindatetime -includes: [compareArray.js] +includes: [compareArray.js, temporalHelpers.js] ---*/ const actual = []; const expected = [ - "get Temporal.Calendar.from", "get timeZone.getOffsetNanosecondsFor", + "get timeZone.getPossibleInstantsFor", + "get timeZone.toString", + "get Temporal.Calendar.from", "call timeZone.getOffsetNanosecondsFor", ]; -const timeZone = new Proxy({ +const timeZone = new Proxy(Object.assign({}, MINIMAL_TIME_ZONE_OBJECT, { getOffsetNanosecondsFor(instant) { actual.push("call timeZone.getOffsetNanosecondsFor"); assert.sameValue(instant instanceof Temporal.Instant, true, "Instant"); return -Number(instant.epochNanoseconds % 86400_000_000_000n); }, -}, { +}), { has(target, property) { actual.push(`has timeZone.${property}`); return property in target; diff --git a/polyfill/test/now/plainDateTime/calendar-function.js b/polyfill/test/now/plainDateTime/calendar-function.js index 7b907dad81..44039d0410 100644 --- a/polyfill/test/now/plainDateTime/calendar-function.js +++ b/polyfill/test/now/plainDateTime/calendar-function.js @@ -9,16 +9,18 @@ includes: [compareArray.js, temporalHelpers.js] const actual = []; const expected = [ "get timeZone.getOffsetNanosecondsFor", + "get timeZone.getPossibleInstantsFor", + "get timeZone.toString", "call timeZone.getOffsetNanosecondsFor", ]; const calendar = Object.assign(function() {}, MINIMAL_CALENDAR_OBJECT); -const timeZone = new Proxy({ +const timeZone = new Proxy(Object.assign({}, MINIMAL_TIME_ZONE_OBJECT, { getOffsetNanosecondsFor(instant) { actual.push("call timeZone.getOffsetNanosecondsFor"); assert.sameValue(instant instanceof Temporal.Instant, true, "Instant"); return -Number(instant.epochNanoseconds % 86400_000_000_000n); }, -}, { +}), { has(target, property) { actual.push(`has timeZone.${property}`); return property in target; diff --git a/polyfill/test/now/plainDateTime/calendar-object.js b/polyfill/test/now/plainDateTime/calendar-object.js index 8cad8fc37d..cf7f456b1c 100644 --- a/polyfill/test/now/plainDateTime/calendar-object.js +++ b/polyfill/test/now/plainDateTime/calendar-object.js @@ -9,16 +9,18 @@ includes: [compareArray.js, temporalHelpers.js] const actual = []; const expected = [ "get timeZone.getOffsetNanosecondsFor", + "get timeZone.getPossibleInstantsFor", + "get timeZone.toString", "call timeZone.getOffsetNanosecondsFor", ]; const calendar = MINIMAL_CALENDAR_OBJECT; -const timeZone = new Proxy({ +const timeZone = new Proxy(Object.assign({}, MINIMAL_TIME_ZONE_OBJECT, { getOffsetNanosecondsFor(instant) { actual.push("call timeZone.getOffsetNanosecondsFor"); assert.sameValue(instant instanceof Temporal.Instant, true, "Instant"); return -Number(instant.epochNanoseconds % 86400_000_000_000n); }, -}, { +}), { has(target, property) { actual.push(`has timeZone.${property}`); return property in target; diff --git a/polyfill/test/now/plainDateTime/calendar.js b/polyfill/test/now/plainDateTime/calendar.js index 3e5fe68881..84a0e71607 100644 --- a/polyfill/test/now/plainDateTime/calendar.js +++ b/polyfill/test/now/plainDateTime/calendar.js @@ -10,21 +10,23 @@ const actual = []; const expected = [ "get Temporal.TimeZone.from", "call Temporal.TimeZone.from", + "get timeZone.getOffsetNanosecondsFor", + "get timeZone.getPossibleInstantsFor", + "get timeZone.toString", "get Temporal.Calendar.from", "call Temporal.Calendar.from", - "get timeZone.getOffsetNanosecondsFor", "call timeZone.getOffsetNanosecondsFor", ]; const calendar = MINIMAL_CALENDAR_OBJECT; -const timeZone = new Proxy({ +const timeZone = new Proxy(Object.assign({}, MINIMAL_TIME_ZONE_OBJECT, { getOffsetNanosecondsFor(instant) { actual.push("call timeZone.getOffsetNanosecondsFor"); assert.sameValue(instant instanceof Temporal.Instant, true, "Instant"); return -Number(instant.epochNanoseconds % 86400_000_000_000n); }, -}, { +}), { has(target, property) { actual.push(`has timeZone.${property}`); return property in target; diff --git a/polyfill/test/now/plainDateTime/timezone-object.js b/polyfill/test/now/plainDateTime/timezone-object.js index aa7a207345..6fbc63fc56 100644 --- a/polyfill/test/now/plainDateTime/timezone-object.js +++ b/polyfill/test/now/plainDateTime/timezone-object.js @@ -3,22 +3,24 @@ /*--- esid: sec-temporal.now.plaindatetime -includes: [compareArray.js] +includes: [compareArray.js, temporalHelpers.js] ---*/ const actual = []; const expected = [ "get timeZone.getOffsetNanosecondsFor", + "get timeZone.getPossibleInstantsFor", + "get timeZone.toString", "call timeZone.getOffsetNanosecondsFor", ]; -const timeZone = new Proxy({ +const timeZone = new Proxy(Object.assign({}, MINIMAL_TIME_ZONE_OBJECT, { getOffsetNanosecondsFor(instant) { actual.push("call timeZone.getOffsetNanosecondsFor"); assert.sameValue(instant instanceof Temporal.Instant, true, "Instant"); return -Number(instant.epochNanoseconds % 86400_000_000_000n); }, -}, { +}), { has(target, property) { actual.push(`has timeZone.${property}`); return property in target; diff --git a/polyfill/test/now/plainDateTime/timezone.js b/polyfill/test/now/plainDateTime/timezone.js index e48930a287..6ba87d29b2 100644 --- a/polyfill/test/now/plainDateTime/timezone.js +++ b/polyfill/test/now/plainDateTime/timezone.js @@ -3,7 +3,7 @@ /*--- esid: sec-temporal.now.plaindatetime -includes: [compareArray.js] +includes: [compareArray.js, temporalHelpers.js] ---*/ const actual = []; @@ -11,16 +11,18 @@ const expected = [ "get Temporal.TimeZone.from", "call Temporal.TimeZone.from", "get timeZone.getOffsetNanosecondsFor", + "get timeZone.getPossibleInstantsFor", + "get timeZone.toString", "call timeZone.getOffsetNanosecondsFor", ]; -const timeZone = new Proxy({ +const timeZone = new Proxy(Object.assign({}, MINIMAL_TIME_ZONE_OBJECT, { getOffsetNanosecondsFor(instant) { actual.push("call timeZone.getOffsetNanosecondsFor"); assert.sameValue(instant instanceof Temporal.Instant, true, "Instant"); return -Number(instant.epochNanoseconds % 86400_000_000_000n); }, -}, { +}), { has(target, property) { actual.push(`has timeZone.${property}`); return property in target; diff --git a/polyfill/test/now/plainTimeISO/timezone-object.js b/polyfill/test/now/plainTimeISO/timezone-object.js index 10e7f20f17..677370c0c6 100644 --- a/polyfill/test/now/plainTimeISO/timezone-object.js +++ b/polyfill/test/now/plainTimeISO/timezone-object.js @@ -3,22 +3,24 @@ /*--- esid: sec-temporal.now.plaintimeiso -includes: [compareArray.js] +includes: [compareArray.js, temporalHelpers.js] ---*/ const actual = []; const expected = [ "get timeZone.getOffsetNanosecondsFor", + "get timeZone.getPossibleInstantsFor", + "get timeZone.toString", "call timeZone.getOffsetNanosecondsFor", ]; -const timeZone = new Proxy({ +const timeZone = new Proxy(Object.assign({}, MINIMAL_TIME_ZONE_OBJECT, { getOffsetNanosecondsFor(instant) { actual.push("call timeZone.getOffsetNanosecondsFor"); assert.sameValue(instant instanceof Temporal.Instant, true, "Instant"); return -Number(instant.epochNanoseconds % 86400_000_000_000n); }, -}, { +}), { has(target, property) { actual.push(`has timeZone.${property}`); return property in target; diff --git a/polyfill/test/now/plainTimeISO/timezone.js b/polyfill/test/now/plainTimeISO/timezone.js index f9ab51252a..0559267f41 100644 --- a/polyfill/test/now/plainTimeISO/timezone.js +++ b/polyfill/test/now/plainTimeISO/timezone.js @@ -3,7 +3,7 @@ /*--- esid: sec-temporal.now.plaintimeiso -includes: [compareArray.js] +includes: [compareArray.js, temporalHelpers.js] ---*/ const actual = []; @@ -11,16 +11,18 @@ const expected = [ "get Temporal.TimeZone.from", "call Temporal.TimeZone.from", "get timeZone.getOffsetNanosecondsFor", + "get timeZone.getPossibleInstantsFor", + "get timeZone.toString", "call timeZone.getOffsetNanosecondsFor", ]; -const timeZone = new Proxy({ +const timeZone = new Proxy(Object.assign({}, MINIMAL_TIME_ZONE_OBJECT, { getOffsetNanosecondsFor(instant) { actual.push("call timeZone.getOffsetNanosecondsFor"); assert.sameValue(instant instanceof Temporal.Instant, true, "Instant"); return -Number(instant.epochNanoseconds % 86400_000_000_000n); }, -}, { +}), { has(target, property) { actual.push(`has timeZone.${property}`); return property in target; diff --git a/polyfill/test/now/plainTimeISO/toTime-override.js b/polyfill/test/now/plainTimeISO/toTime-override.js index 50b7873f85..ff192bc83c 100644 --- a/polyfill/test/now/plainTimeISO/toTime-override.js +++ b/polyfill/test/now/plainTimeISO/toTime-override.js @@ -3,7 +3,7 @@ /*--- esid: sec-temporal.now.plaintimeiso -includes: [compareArray.js] +includes: [compareArray.js, temporalHelpers.js] ---*/ const actual = []; @@ -11,6 +11,8 @@ const expected = [ "get Temporal.TimeZone.from", "call Temporal.TimeZone.from", "get timeZone.getOffsetNanosecondsFor", + "get timeZone.getPossibleInstantsFor", + "get timeZone.toString", "call timeZone.getOffsetNanosecondsFor", ]; @@ -23,13 +25,13 @@ Object.defineProperty(Temporal.PlainDateTime.prototype, "toPlainTime", { }, }); -const timeZone = new Proxy({ +const timeZone = new Proxy(Object.assign({}, MINIMAL_TIME_ZONE_OBJECT, { getOffsetNanosecondsFor(instant) { actual.push("call timeZone.getOffsetNanosecondsFor"); assert.sameValue(instant instanceof Temporal.Instant, true, "Instant"); return -Number(instant.epochNanoseconds % 86400_000_000_000n); }, -}, { +}), { has(target, property) { actual.push(`has timeZone.${property}`); return property in target;