@js-temporal/polyfill
Version:
Polyfill for Tc39 Stage 3 proposal Temporal (https://github.com/tc39/proposal-temporal)
554 lines (535 loc) • 24.4 kB
text/typescript
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));
}