UNPKG

@js-temporal/polyfill

Version:

Polyfill for Temporal (https://github.com/tc39/proposal-temporal), an ECMA TC39 Stage 3 proposal

155 lines (142 loc) 6.84 kB
import * as ES from './ecmascript'; import { MakeIntrinsicClass } from './intrinsicclass'; import { GetSlot, TIME } from './slots'; import type { Temporal } from '..'; import { DateTimeFormat } from './intl'; import type { PlainTimeParams as Params, PlainTimeReturn as Return } from './internaltypes'; export class PlainTime implements Temporal.PlainTime { constructor(isoHour = 0, isoMinute = 0, isoSecond = 0, isoMillisecond = 0, isoMicrosecond = 0, isoNanosecond = 0) { const hour = isoHour === undefined ? 0 : ES.ToIntegerWithTruncation(isoHour); const minute = isoMinute === undefined ? 0 : ES.ToIntegerWithTruncation(isoMinute); const second = isoSecond === undefined ? 0 : ES.ToIntegerWithTruncation(isoSecond); const millisecond = isoMillisecond === undefined ? 0 : ES.ToIntegerWithTruncation(isoMillisecond); const microsecond = isoMicrosecond === undefined ? 0 : ES.ToIntegerWithTruncation(isoMicrosecond); const nanosecond = isoNanosecond === undefined ? 0 : ES.ToIntegerWithTruncation(isoNanosecond); ES.RejectTime(hour, minute, second, millisecond, microsecond, nanosecond); const time = { hour, minute, second, millisecond, microsecond, nanosecond }; ES.CreateTemporalTimeSlots(this, time); } get hour(): Return['hour'] { ES.CheckReceiver(this, ES.IsTemporalTime); return GetSlot(this, TIME).hour; } get minute(): Return['minute'] { ES.CheckReceiver(this, ES.IsTemporalTime); return GetSlot(this, TIME).minute; } get second(): Return['second'] { ES.CheckReceiver(this, ES.IsTemporalTime); return GetSlot(this, TIME).second; } get millisecond(): Return['millisecond'] { ES.CheckReceiver(this, ES.IsTemporalTime); return GetSlot(this, TIME).millisecond; } get microsecond(): Return['microsecond'] { ES.CheckReceiver(this, ES.IsTemporalTime); return GetSlot(this, TIME).microsecond; } get nanosecond(): Return['nanosecond'] { ES.CheckReceiver(this, ES.IsTemporalTime); return GetSlot(this, TIME).nanosecond; } with(temporalTimeLike: Params['with'][0], options: Params['with'][1] = undefined): Return['with'] { ES.CheckReceiver(this, ES.IsTemporalTime); if (!ES.IsObject(temporalTimeLike)) { throw new TypeError('invalid argument'); } ES.RejectTemporalLikeObject(temporalTimeLike); const partialTime = ES.ToTemporalTimeRecord(temporalTimeLike, 'partial'); const fields = ES.ToTemporalTimeRecord(this); let { hour, minute, second, millisecond, microsecond, nanosecond } = Object.assign(fields, partialTime); const overflow = ES.GetTemporalOverflowOption(ES.GetOptionsObject(options)); ({ hour, minute, second, millisecond, microsecond, nanosecond } = ES.RegulateTime( hour, minute, second, millisecond, microsecond, nanosecond, overflow )); return new PlainTime(hour, minute, second, millisecond, microsecond, nanosecond); } add(temporalDurationLike: Params['add'][0]): Return['add'] { ES.CheckReceiver(this, ES.IsTemporalTime); return ES.AddDurationToTime('add', this, temporalDurationLike); } subtract(temporalDurationLike: Params['subtract'][0]): Return['subtract'] { ES.CheckReceiver(this, ES.IsTemporalTime); return ES.AddDurationToTime('subtract', this, temporalDurationLike); } until(other: Params['until'][0], options: Params['until'][1] = undefined): Return['until'] { ES.CheckReceiver(this, ES.IsTemporalTime); return ES.DifferenceTemporalPlainTime('until', this, other, options); } since(other: Params['since'][0], options: Params['since'][1] = undefined): Return['since'] { ES.CheckReceiver(this, ES.IsTemporalTime); return ES.DifferenceTemporalPlainTime('since', this, other, options); } round(roundToParam: Params['round'][0]): Return['round'] { ES.CheckReceiver(this, ES.IsTemporalTime); if (roundToParam === undefined) throw new TypeError('options parameter is required'); const roundTo = typeof roundToParam === 'string' ? (ES.CreateOnePropObject('smallestUnit', roundToParam) as Exclude<typeof roundToParam, string>) : ES.GetOptionsObject(roundToParam); const roundingIncrement = ES.GetTemporalRoundingIncrementOption(roundTo); const roundingMode = ES.GetRoundingModeOption(roundTo, 'halfExpand'); const smallestUnit = ES.GetTemporalUnitValuedOption(roundTo, 'smallestUnit', 'time', ES.REQUIRED); const MAX_INCREMENTS = { hour: 24, minute: 60, second: 60, millisecond: 1000, microsecond: 1000, nanosecond: 1000 }; ES.ValidateTemporalRoundingIncrement(roundingIncrement, MAX_INCREMENTS[smallestUnit], false); const time = ES.RoundTime(GetSlot(this, TIME), roundingIncrement, smallestUnit, roundingMode); return ES.CreateTemporalTime(time); } equals(otherParam: Params['equals'][0]): Return['equals'] { ES.CheckReceiver(this, ES.IsTemporalTime); const other = ES.ToTemporalTime(otherParam); return ES.CompareTimeRecord(GetSlot(this, TIME), GetSlot(other, TIME)) === 0; } toString(options: Params['toString'][0] = undefined): string { ES.CheckReceiver(this, ES.IsTemporalTime); const resolvedOptions = ES.GetOptionsObject(options); const digits = ES.GetTemporalFractionalSecondDigitsOption(resolvedOptions); const roundingMode = ES.GetRoundingModeOption(resolvedOptions, 'trunc'); const smallestUnit = ES.GetTemporalUnitValuedOption(resolvedOptions, 'smallestUnit', 'time', undefined); if (smallestUnit === 'hour') throw new RangeError('smallestUnit must be a time unit other than "hour"'); const { precision, unit, increment } = ES.ToSecondsStringPrecisionRecord(smallestUnit, digits); const time = ES.RoundTime(GetSlot(this, TIME), increment, unit, roundingMode); return ES.TimeRecordToString(time, precision); } toJSON(): Return['toJSON'] { ES.CheckReceiver(this, ES.IsTemporalTime); return ES.TimeRecordToString(GetSlot(this, TIME), 'auto'); } toLocaleString( locales: Params['toLocaleString'][0] = undefined, options: Params['toLocaleString'][1] = undefined ): string { ES.CheckReceiver(this, ES.IsTemporalTime); return new DateTimeFormat(locales, options).format(this); } valueOf(): never { ES.ValueOfThrows('PlainTime'); } static from(item: Params['from'][0], options: Params['from'][1] = undefined): Return['from'] { return ES.ToTemporalTime(item, options); } static compare(oneParam: Params['compare'][0], twoParam: Params['compare'][1]): Return['compare'] { const one = ES.ToTemporalTime(oneParam); const two = ES.ToTemporalTime(twoParam); return ES.CompareTimeRecord(GetSlot(one, TIME), GetSlot(two, TIME)); } [Symbol.toStringTag]!: 'Temporal.PlainTime'; } MakeIntrinsicClass(PlainTime, 'Temporal.PlainTime');