UNPKG

@js-temporal/polyfill

Version:

Polyfill for Tc39 Stage 3 proposal Temporal (https://github.com/tc39/proposal-temporal)

554 lines (535 loc) 24.4 kB
import * as ES from './ecmascript'; import { GetIntrinsic, MakeIntrinsicClass } from './intrinsicclass'; import { CALENDAR, EPOCHNANOSECONDS, ISO_HOUR, INSTANT, ISO_DAY, ISO_MONTH, ISO_YEAR, ISO_MICROSECOND, ISO_MILLISECOND, ISO_MINUTE, ISO_NANOSECOND, ISO_SECOND, TIME_ZONE, GetSlot } from './slots'; import type { Temporal } from '..'; import { DateTimeFormat } from './intl'; import type { ZonedDateTimeParams as Params, ZonedDateTimeReturn as Return } from './internaltypes'; import JSBI from 'jsbi'; import { BILLION, MILLION, THOUSAND, ZERO } from './ecmascript'; export class ZonedDateTime implements Temporal.ZonedDateTime { constructor( epochNanosecondsParam: bigint | JSBI, timeZoneParam: Temporal.TimeZoneProtocol | string, calendarParam: Temporal.CalendarProtocol | string = ES.GetISO8601Calendar() ) { // Note: if the argument is not passed, ToBigInt(undefined) will throw. This check exists only // to improve the error message. // ToTemporalTimeZone(undefined) will end up calling TimeZone.from("undefined"), which // could succeed. if (arguments.length < 1) { throw new TypeError('missing argument: epochNanoseconds is required'); } const epochNanoseconds = ES.ToBigInt(epochNanosecondsParam); const timeZone = ES.ToTemporalTimeZone(timeZoneParam); const calendar = ES.ToTemporalCalendar(calendarParam); ES.CreateTemporalZonedDateTimeSlots(this, epochNanoseconds, timeZone, calendar); } get calendar(): Return['calendar'] { if (!ES.IsTemporalZonedDateTime(this)) throw new TypeError('invalid receiver'); return GetSlot(this, CALENDAR); } get timeZone(): Return['timeZone'] { if (!ES.IsTemporalZonedDateTime(this)) throw new TypeError('invalid receiver'); return GetSlot(this, TIME_ZONE); } get year(): Return['year'] { if (!ES.IsTemporalZonedDateTime(this)) throw new TypeError('invalid receiver'); return ES.CalendarYear(GetSlot(this, CALENDAR), dateTime(this)); } get month(): Return['month'] { if (!ES.IsTemporalZonedDateTime(this)) throw new TypeError('invalid receiver'); return ES.CalendarMonth(GetSlot(this, CALENDAR), dateTime(this)); } get monthCode(): Return['monthCode'] { if (!ES.IsTemporalZonedDateTime(this)) throw new TypeError('invalid receiver'); return ES.CalendarMonthCode(GetSlot(this, CALENDAR), dateTime(this)); } get day(): Return['day'] { if (!ES.IsTemporalZonedDateTime(this)) throw new TypeError('invalid receiver'); return ES.CalendarDay(GetSlot(this, CALENDAR), dateTime(this)); } get hour(): Return['hour'] { if (!ES.IsTemporalZonedDateTime(this)) throw new TypeError('invalid receiver'); return GetSlot(dateTime(this), ISO_HOUR); } get minute(): Return['minute'] { if (!ES.IsTemporalZonedDateTime(this)) throw new TypeError('invalid receiver'); return GetSlot(dateTime(this), ISO_MINUTE); } get second(): Return['second'] { if (!ES.IsTemporalZonedDateTime(this)) throw new TypeError('invalid receiver'); return GetSlot(dateTime(this), ISO_SECOND); } get millisecond(): Return['millisecond'] { if (!ES.IsTemporalZonedDateTime(this)) throw new TypeError('invalid receiver'); return GetSlot(dateTime(this), ISO_MILLISECOND); } get microsecond(): Return['microsecond'] { if (!ES.IsTemporalZonedDateTime(this)) throw new TypeError('invalid receiver'); return GetSlot(dateTime(this), ISO_MICROSECOND); } get nanosecond(): Return['nanosecond'] { if (!ES.IsTemporalZonedDateTime(this)) throw new TypeError('invalid receiver'); return GetSlot(dateTime(this), ISO_NANOSECOND); } get era(): Return['era'] { if (!ES.IsTemporalZonedDateTime(this)) throw new TypeError('invalid receiver'); return ES.CalendarEra(GetSlot(this, CALENDAR), dateTime(this)); } get eraYear(): Return['eraYear'] { if (!ES.IsTemporalZonedDateTime(this)) throw new TypeError('invalid receiver'); return ES.CalendarEraYear(GetSlot(this, CALENDAR), dateTime(this)); } get epochSeconds(): Return['epochSeconds'] { if (!ES.IsTemporalZonedDateTime(this)) throw new TypeError('invalid receiver'); const value = GetSlot(this, EPOCHNANOSECONDS); return JSBI.toNumber(JSBI.divide(value, BILLION)); } get epochMilliseconds(): Return['epochMilliseconds'] { if (!ES.IsTemporalZonedDateTime(this)) throw new TypeError('invalid receiver'); const value = GetSlot(this, EPOCHNANOSECONDS); return JSBI.toNumber(JSBI.divide(value, MILLION)); } get epochMicroseconds(): Return['epochMicroseconds'] { if (!ES.IsTemporalZonedDateTime(this)) throw new TypeError('invalid receiver'); const value = GetSlot(this, EPOCHNANOSECONDS); return ES.ToBigIntExternal(JSBI.divide(value, THOUSAND)); } get epochNanoseconds(): Return['epochNanoseconds'] { if (!ES.IsTemporalZonedDateTime(this)) throw new TypeError('invalid receiver'); return ES.ToBigIntExternal(GetSlot(this, EPOCHNANOSECONDS)); } get dayOfWeek(): Return['dayOfWeek'] { if (!ES.IsTemporalZonedDateTime(this)) throw new TypeError('invalid receiver'); return ES.CalendarDayOfWeek(GetSlot(this, CALENDAR), dateTime(this)); } get dayOfYear(): Return['dayOfYear'] { if (!ES.IsTemporalZonedDateTime(this)) throw new TypeError('invalid receiver'); return ES.CalendarDayOfYear(GetSlot(this, CALENDAR), dateTime(this)); } get weekOfYear(): Return['weekOfYear'] { if (!ES.IsTemporalZonedDateTime(this)) throw new TypeError('invalid receiver'); return ES.CalendarWeekOfYear(GetSlot(this, CALENDAR), dateTime(this)); } get hoursInDay(): Return['hoursInDay'] { if (!ES.IsTemporalZonedDateTime(this)) throw new TypeError('invalid receiver'); const dt = dateTime(this); const DateTime = GetIntrinsic('%Temporal.PlainDateTime%'); const year = GetSlot(dt, ISO_YEAR); const month = GetSlot(dt, ISO_MONTH); const day = GetSlot(dt, ISO_DAY); 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); return JSBI.toNumber(JSBI.subtract(tomorrowNs, todayNs)) / 3.6e12; } get daysInWeek(): Return['daysInWeek'] { if (!ES.IsTemporalZonedDateTime(this)) throw new TypeError('invalid receiver'); return ES.CalendarDaysInWeek(GetSlot(this, CALENDAR), dateTime(this)); } get daysInMonth(): Return['daysInMonth'] { if (!ES.IsTemporalZonedDateTime(this)) throw new TypeError('invalid receiver'); return ES.CalendarDaysInMonth(GetSlot(this, CALENDAR), dateTime(this)); } get daysInYear(): Return['daysInYear'] { if (!ES.IsTemporalZonedDateTime(this)) throw new TypeError('invalid receiver'); return ES.CalendarDaysInYear(GetSlot(this, CALENDAR), dateTime(this)); } get monthsInYear(): Return['monthsInYear'] { if (!ES.IsTemporalZonedDateTime(this)) throw new TypeError('invalid receiver'); return ES.CalendarMonthsInYear(GetSlot(this, CALENDAR), dateTime(this)); } get inLeapYear(): Return['inLeapYear'] { if (!ES.IsTemporalZonedDateTime(this)) throw new TypeError('invalid receiver'); return ES.CalendarInLeapYear(GetSlot(this, CALENDAR), dateTime(this)); } get offset(): Return['offset'] { if (!ES.IsTemporalZonedDateTime(this)) throw new TypeError('invalid receiver'); return ES.BuiltinTimeZoneGetOffsetStringFor(GetSlot(this, TIME_ZONE), GetSlot(this, INSTANT)); } get offsetNanoseconds(): Return['offsetNanoseconds'] { if (!ES.IsTemporalZonedDateTime(this)) throw new TypeError('invalid receiver'); return ES.GetOffsetNanosecondsFor(GetSlot(this, TIME_ZONE), GetSlot(this, INSTANT)); } with(temporalZonedDateTimeLike: Params['with'][0], optionsParam: Params['with'][1] = undefined): Return['with'] { if (!ES.IsTemporalZonedDateTime(this)) throw new TypeError('invalid receiver'); if (!ES.IsObject(temporalZonedDateTimeLike)) { throw new TypeError('invalid zoned-date-time-like'); } ES.RejectObjectWithCalendarOrTimeZone(temporalZonedDateTimeLike); // TODO: Reorder according to spec. const options = ES.GetOptionsObject(optionsParam); const disambiguation = ES.ToTemporalDisambiguation(options); const offset = ES.ToTemporalOffset(options, 'prefer'); const timeZone = GetSlot(this, TIME_ZONE); const calendar = GetSlot(this, CALENDAR); const fieldNames = ES.CalendarFields(calendar, [ 'day', 'hour', 'microsecond', 'millisecond', 'minute', 'month', 'monthCode', 'nanosecond', 'second', 'year' ] as const); const fieldsWithOffset = ES.ArrayPush(fieldNames, 'offset'); const props = ES.PrepareTemporalFields(temporalZonedDateTimeLike, fieldsWithOffset, 'partial'); const fieldsWithTimeZoneAndOffset = ES.ArrayPush(fieldsWithOffset, 'timeZone'); let fields = ES.PrepareTemporalFields(this, fieldsWithTimeZoneAndOffset, ['timeZone', 'offset']); fields = ES.CalendarMergeFields(calendar, fields, props); fields = ES.PrepareTemporalFields(fields, fieldsWithTimeZoneAndOffset, ['timeZone', 'offset']); let { year, month, day, hour, minute, second, millisecond, microsecond, nanosecond } = ES.InterpretTemporalDateTimeFields(calendar, fields, options); const offsetNs = ES.ParseTimeZoneOffsetString(fields.offset); const epochNanoseconds = ES.InterpretISODateTimeOffset( year, month, day, hour, minute, second, millisecond, microsecond, nanosecond, 'option', offsetNs, timeZone, disambiguation, offset, /* matchMinute = */ false ); return ES.CreateTemporalZonedDateTime(epochNanoseconds, GetSlot(this, TIME_ZONE), calendar); } withPlainDate(temporalDateParam: Params['withPlainDate'][0]): Return['withPlainDate'] { if (!ES.IsTemporalZonedDateTime(this)) throw new TypeError('invalid receiver'); const temporalDate = ES.ToTemporalDate(temporalDateParam); const year = GetSlot(temporalDate, ISO_YEAR); const month = GetSlot(temporalDate, ISO_MONTH); const day = GetSlot(temporalDate, ISO_DAY); let calendar = GetSlot(temporalDate, CALENDAR); const thisDt = dateTime(this); const hour = GetSlot(thisDt, ISO_HOUR); const minute = GetSlot(thisDt, ISO_MINUTE); const second = GetSlot(thisDt, ISO_SECOND); const millisecond = GetSlot(thisDt, ISO_MILLISECOND); const microsecond = GetSlot(thisDt, ISO_MICROSECOND); const nanosecond = GetSlot(thisDt, ISO_NANOSECOND); calendar = ES.ConsolidateCalendars(GetSlot(this, CALENDAR), calendar); const timeZone = GetSlot(this, TIME_ZONE); const PlainDateTime = GetIntrinsic('%Temporal.PlainDateTime%'); const dt = new PlainDateTime( year, month, day, hour, minute, second, millisecond, microsecond, nanosecond, calendar ); const instant = ES.BuiltinTimeZoneGetInstantFor(timeZone, dt, 'compatible'); return ES.CreateTemporalZonedDateTime(GetSlot(instant, EPOCHNANOSECONDS), timeZone, calendar); } withPlainTime(temporalTimeParam: Params['withPlainTime'][0] = undefined): Return['withPlainTime'] { if (!ES.IsTemporalZonedDateTime(this)) throw new TypeError('invalid receiver'); const PlainTime = GetIntrinsic('%Temporal.PlainTime%'); const temporalTime = temporalTimeParam === undefined ? new PlainTime() : ES.ToTemporalTime(temporalTimeParam); const thisDt = dateTime(this); const year = GetSlot(thisDt, ISO_YEAR); const month = GetSlot(thisDt, ISO_MONTH); const day = GetSlot(thisDt, ISO_DAY); const calendar = GetSlot(this, CALENDAR); const hour = GetSlot(temporalTime, ISO_HOUR); const minute = GetSlot(temporalTime, ISO_MINUTE); const second = GetSlot(temporalTime, ISO_SECOND); const millisecond = GetSlot(temporalTime, ISO_MILLISECOND); const microsecond = GetSlot(temporalTime, ISO_MICROSECOND); const nanosecond = GetSlot(temporalTime, ISO_NANOSECOND); const timeZone = GetSlot(this, TIME_ZONE); const PlainDateTime = GetIntrinsic('%Temporal.PlainDateTime%'); const dt = new PlainDateTime( year, month, day, hour, minute, second, millisecond, microsecond, nanosecond, calendar ); const instant = ES.BuiltinTimeZoneGetInstantFor(timeZone, dt, 'compatible'); return ES.CreateTemporalZonedDateTime(GetSlot(instant, EPOCHNANOSECONDS), timeZone, calendar); } withTimeZone(timeZoneParam: Params['withTimeZone'][0]): Return['withTimeZone'] { if (!ES.IsTemporalZonedDateTime(this)) throw new TypeError('invalid receiver'); const timeZone = ES.ToTemporalTimeZone(timeZoneParam); return ES.CreateTemporalZonedDateTime(GetSlot(this, EPOCHNANOSECONDS), timeZone, GetSlot(this, CALENDAR)); } withCalendar(calendarParam: Params['withCalendar'][0]): Return['withCalendar'] { if (!ES.IsTemporalZonedDateTime(this)) throw new TypeError('invalid receiver'); const calendar = ES.ToTemporalCalendar(calendarParam); return ES.CreateTemporalZonedDateTime(GetSlot(this, EPOCHNANOSECONDS), GetSlot(this, TIME_ZONE), calendar); } add(temporalDurationLike: Params['add'][0], options: Params['add'][1] = undefined): Return['add'] { if (!ES.IsTemporalZonedDateTime(this)) throw new TypeError('invalid receiver'); return ES.AddDurationToOrSubtractDurationFromZonedDateTime('add', this, temporalDurationLike, options); } subtract( temporalDurationLike: Params['subtract'][0], options: Params['subtract'][1] = undefined ): Return['subtract'] { if (!ES.IsTemporalZonedDateTime(this)) throw new TypeError('invalid receiver'); return ES.AddDurationToOrSubtractDurationFromZonedDateTime('subtract', this, temporalDurationLike, options); } until(other: Params['until'][0], options: Params['until'][1] = undefined): Return['until'] { if (!ES.IsTemporalZonedDateTime(this)) throw new TypeError('invalid receiver'); return ES.DifferenceTemporalZonedDateTime('until', this, other, options); } since(other: Params['since'][0], options: Params['since'][1] = undefined): Return['since'] { if (!ES.IsTemporalZonedDateTime(this)) throw new TypeError('invalid receiver'); return ES.DifferenceTemporalZonedDateTime('since', this, other, options); } round(optionsParam: Params['round'][0]): Return['round'] { if (!ES.IsTemporalZonedDateTime(this)) throw new TypeError('invalid receiver'); if (optionsParam === undefined) throw new TypeError('options parameter is required'); const options = typeof optionsParam === 'string' ? (ES.CreateOnePropObject('smallestUnit', optionsParam) as Exclude<typeof optionsParam, string>) : ES.GetOptionsObject(optionsParam); const smallestUnit = ES.GetTemporalUnit(options, 'smallestUnit', 'time', ES.REQUIRED, ['day']); const roundingMode = ES.ToTemporalRoundingMode(options, 'halfExpand'); const maximumIncrements = { day: 1, hour: 24, minute: 60, second: 60, millisecond: 1000, microsecond: 1000, nanosecond: 1000 }; const roundingIncrement = ES.ToTemporalRoundingIncrement(options, maximumIncrements[smallestUnit], false); // first, round the underlying DateTime fields const dt = dateTime(this); let year = GetSlot(dt, ISO_YEAR); let month = GetSlot(dt, ISO_MONTH); let day = GetSlot(dt, ISO_DAY); let hour = GetSlot(dt, ISO_HOUR); let minute = GetSlot(dt, ISO_MINUTE); let second = GetSlot(dt, ISO_SECOND); let millisecond = GetSlot(dt, ISO_MILLISECOND); let microsecond = GetSlot(dt, ISO_MICROSECOND); let nanosecond = GetSlot(dt, ISO_NANOSECOND); const DateTime = GetIntrinsic('%Temporal.PlainDateTime%'); const timeZone = GetSlot(this, TIME_ZONE); const calendar = GetSlot(this, CALENDAR); 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, calendar, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0); const dayLengthNs = JSBI.subtract(endNs, JSBI.BigInt(GetSlot(instantStart, EPOCHNANOSECONDS))); if (JSBI.equal(dayLengthNs, ZERO)) { throw new RangeError('cannot round a ZonedDateTime in a calendar with zero-length days'); } ({ year, month, day, hour, minute, second, millisecond, microsecond, nanosecond } = ES.RoundISODateTime( year, month, day, hour, minute, second, millisecond, microsecond, nanosecond, roundingIncrement, smallestUnit, roundingMode, // Days are guaranteed to be shorter than Number.MAX_SAFE_INTEGER // (which can hold up to 104 days in nanoseconds) JSBI.toNumber(dayLengthNs) )); // Now reset all DateTime fields but leave the TimeZone. The offset will // also be retained if the new date/time values are still OK with the old // 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 epochNanoseconds = ES.InterpretISODateTimeOffset( year, month, day, hour, minute, second, millisecond, microsecond, nanosecond, 'option', offsetNs, timeZone, 'compatible', 'prefer', /* matchMinute = */ false ); return ES.CreateTemporalZonedDateTime(epochNanoseconds, timeZone, GetSlot(this, CALENDAR)); } equals(otherParam: Params['equals'][0]): Return['equals'] { if (!ES.IsTemporalZonedDateTime(this)) throw new TypeError('invalid receiver'); const other = ES.ToTemporalZonedDateTime(otherParam); const one = GetSlot(this, EPOCHNANOSECONDS); const two = GetSlot(other, EPOCHNANOSECONDS); if (!JSBI.equal(JSBI.BigInt(one), JSBI.BigInt(two))) return false; if (!ES.TimeZoneEquals(GetSlot(this, TIME_ZONE), GetSlot(other, TIME_ZONE))) return false; return ES.CalendarEquals(GetSlot(this, CALENDAR), GetSlot(other, CALENDAR)); } toString(optionsParam: Params['toString'][0] = undefined): string { if (!ES.IsTemporalZonedDateTime(this)) throw new TypeError('invalid receiver'); const options = ES.GetOptionsObject(optionsParam); const { precision, unit, increment } = ES.ToSecondsStringPrecision(options); const roundingMode = ES.ToTemporalRoundingMode(options, 'trunc'); const showCalendar = ES.ToShowCalendarOption(options); const showTimeZone = ES.ToShowTimeZoneNameOption(options); const showOffset = ES.ToShowOffsetOption(options); return ES.TemporalZonedDateTimeToString(this, precision, showCalendar, showTimeZone, showOffset, { unit, increment, roundingMode }); } toLocaleString( locales: Params['toLocaleString'][0] = undefined, options: Params['toLocaleString'][1] = undefined ): string { if (!ES.IsTemporalZonedDateTime(this)) throw new TypeError('invalid receiver'); return new DateTimeFormat(locales, options).format(this); } toJSON(): Return['toJSON'] { if (!ES.IsTemporalZonedDateTime(this)) throw new TypeError('invalid receiver'); return ES.TemporalZonedDateTimeToString(this, 'auto'); } valueOf(): never { throw new TypeError('use compare() or equals() to compare Temporal.ZonedDateTime'); } startOfDay(): Return['startOfDay'] { if (!ES.IsTemporalZonedDateTime(this)) throw new TypeError('invalid receiver'); const dt = dateTime(this); const DateTime = GetIntrinsic('%Temporal.PlainDateTime%'); const calendar = GetSlot(this, CALENDAR); const dtStart = new DateTime( GetSlot(dt, ISO_YEAR), GetSlot(dt, ISO_MONTH), GetSlot(dt, ISO_DAY), 0, 0, 0, 0, 0, 0, calendar ); const timeZone = GetSlot(this, TIME_ZONE); const instant = ES.BuiltinTimeZoneGetInstantFor(timeZone, dtStart, 'compatible'); return ES.CreateTemporalZonedDateTime(GetSlot(instant, EPOCHNANOSECONDS), timeZone, calendar); } toInstant(): Return['toInstant'] { if (!ES.IsTemporalZonedDateTime(this)) throw new TypeError('invalid receiver'); const TemporalInstant = GetIntrinsic('%Temporal.Instant%'); return new TemporalInstant(GetSlot(this, EPOCHNANOSECONDS)); } toPlainDate(): Return['toPlainDate'] { if (!ES.IsTemporalZonedDateTime(this)) throw new TypeError('invalid receiver'); return ES.TemporalDateTimeToDate(dateTime(this)); } toPlainTime(): Return['toPlainTime'] { if (!ES.IsTemporalZonedDateTime(this)) throw new TypeError('invalid receiver'); return ES.TemporalDateTimeToTime(dateTime(this)); } toPlainDateTime(): Return['toPlainDateTime'] { if (!ES.IsTemporalZonedDateTime(this)) throw new TypeError('invalid receiver'); return dateTime(this); } toPlainYearMonth(): Return['toPlainYearMonth'] { if (!ES.IsTemporalZonedDateTime(this)) throw new TypeError('invalid receiver'); const calendar = GetSlot(this, CALENDAR); const fieldNames = ES.CalendarFields(calendar, ['monthCode', 'year'] as const); const fields = ES.PrepareTemporalFields(this, fieldNames, []); return ES.CalendarYearMonthFromFields(calendar, fields); } toPlainMonthDay(): Return['toPlainMonthDay'] { if (!ES.IsTemporalZonedDateTime(this)) throw new TypeError('invalid receiver'); const calendar = GetSlot(this, CALENDAR); const fieldNames = ES.CalendarFields(calendar, ['day', 'monthCode'] as const); const fields = ES.PrepareTemporalFields(this, fieldNames, []); return ES.CalendarMonthDayFromFields(calendar, fields); } getISOFields(): Return['getISOFields'] { if (!ES.IsTemporalZonedDateTime(this)) throw new TypeError('invalid receiver'); const dt = dateTime(this); const tz = GetSlot(this, TIME_ZONE); return { calendar: GetSlot(this, CALENDAR), isoDay: GetSlot(dt, ISO_DAY), isoHour: GetSlot(dt, ISO_HOUR), isoMicrosecond: GetSlot(dt, ISO_MICROSECOND), isoMillisecond: GetSlot(dt, ISO_MILLISECOND), isoMinute: GetSlot(dt, ISO_MINUTE), isoMonth: GetSlot(dt, ISO_MONTH), isoNanosecond: GetSlot(dt, ISO_NANOSECOND), isoSecond: GetSlot(dt, ISO_SECOND), isoYear: GetSlot(dt, ISO_YEAR), offset: ES.BuiltinTimeZoneGetOffsetStringFor(tz, GetSlot(this, INSTANT)), timeZone: tz }; } static from(item: Params['from'][0], optionsParam: Params['from'][1] = undefined): Return['from'] { const options = ES.GetOptionsObject(optionsParam); if (ES.IsTemporalZonedDateTime(item)) { ES.ToTemporalOverflow(options); // validate and ignore ES.ToTemporalDisambiguation(options); ES.ToTemporalOffset(options, 'reject'); return ES.CreateTemporalZonedDateTime( GetSlot(item, EPOCHNANOSECONDS), GetSlot(item, TIME_ZONE), GetSlot(item, CALENDAR) ); } return ES.ToTemporalZonedDateTime(item, options); } static compare(oneParam: Params['compare'][0], twoParam: Params['compare'][1]): Return['compare'] { const one = ES.ToTemporalZonedDateTime(oneParam); const two = ES.ToTemporalZonedDateTime(twoParam); const ns1 = GetSlot(one, EPOCHNANOSECONDS); const ns2 = GetSlot(two, EPOCHNANOSECONDS); if (JSBI.lessThan(JSBI.BigInt(ns1), JSBI.BigInt(ns2))) return -1; if (JSBI.greaterThan(JSBI.BigInt(ns1), JSBI.BigInt(ns2))) return 1; return 0; } [Symbol.toStringTag]!: 'Temporal.ZonedDateTime'; } MakeIntrinsicClass(ZonedDateTime, 'Temporal.ZonedDateTime'); function dateTime(zdt: Temporal.ZonedDateTime) { return ES.BuiltinTimeZoneGetPlainDateTimeFor(GetSlot(zdt, TIME_ZONE), GetSlot(zdt, INSTANT), GetSlot(zdt, CALENDAR)); }