Files
ask262/engine262/src/abstract-ops/temporal/plain-month-day.mts
T

86 lines
4.2 KiB
TypeScript

import type { ISODateRecord } from '../../intrinsics/Temporal/PlainDate.mts';
import { type TemporalPlainMonthDayObject, isTemporalPlainMonthDayObject } from '../../intrinsics/Temporal/PlainMonthDay.mts';
import { ParseISODateTime } from '../../parser/TemporalParser.mts';
import { GetOptionsObject, ToZeroPaddedDecimalString } from './addition.mts';
import {
Value, type ValueEvaluator, ObjectValue, Q, GetTemporalOverflowOption, X, GetTemporalCalendarIdentifierWithISODefault, PrepareCalendarFields, CalendarMonthDayFromFields, JSStringValue, Throw, CanonicalizeCalendar, CreateISODateRecord, ISODateWithinLimits, ISODateToFields, type CalendarType, type FunctionObject, surroundingAgent, OrdinaryCreateFromConstructor, type Mutable, PadISOYear, FormatCalendarAnnotation,
} from '#self';
/** https://tc39.es/proposal-temporal/#sec-temporal-totemporalmonthday */
export function* ToTemporalMonthDay(
item: Value,
options: Value = Value.undefined,
): ValueEvaluator<TemporalPlainMonthDayObject> {
if (item instanceof ObjectValue) {
if (isTemporalPlainMonthDayObject(item)) {
const resolvedOptions = Q(GetOptionsObject(options));
Q(yield* GetTemporalOverflowOption(resolvedOptions));
return X(CreateTemporalMonthDay(item.ISODate, item.Calendar));
}
const calendar = Q(yield* GetTemporalCalendarIdentifierWithISODefault(item));
const fields = Q(yield* PrepareCalendarFields(calendar, item, ['year', 'month', 'month-code', 'day'], [], []));
const resolvedOptions = Q(GetOptionsObject(options));
const overflow = Q(yield* GetTemporalOverflowOption(resolvedOptions));
const isoDate = Q(yield* CalendarMonthDayFromFields(calendar, fields, overflow));
return X(CreateTemporalMonthDay(isoDate, calendar));
}
if (!(item instanceof JSStringValue)) {
return Throw.TypeError('$1 is not a string', item);
}
const result = Q(ParseISODateTime(item.stringValue(), ['TemporalMonthDayString']));
const calendar = result.Calendar ?? 'iso8601';
const calendarType = Q(CanonicalizeCalendar(calendar));
const resolvedOptions = Q(GetOptionsObject(options));
Q(yield* GetTemporalOverflowOption(resolvedOptions));
if (calendarType === 'iso8601') {
const referenceISOYear = 1972;
const isoDate = CreateISODateRecord(referenceISOYear, result.Month, result.Day);
return X(CreateTemporalMonthDay(isoDate, calendarType));
}
let isoDate = CreateISODateRecord(result.Year!, result.Month, result.Day);
if (!ISODateWithinLimits(isoDate)) {
return Throw.RangeError('PlainMonthDay out of range');
}
const result2 = Q(ISODateToFields(calendarType, isoDate, 'month-day'));
isoDate = Q(yield* CalendarMonthDayFromFields(calendarType, result2, 'constrain'));
return X(CreateTemporalMonthDay(isoDate, calendarType));
}
/** https://tc39.es/proposal-temporal/#sec-temporal-createtemporalmonthday */
export function* CreateTemporalMonthDay(
isoDate: ISODateRecord,
calendar: CalendarType,
newTarget?: FunctionObject,
): ValueEvaluator<TemporalPlainMonthDayObject> {
if (!ISODateWithinLimits(isoDate)) {
return Throw.RangeError('PlainMonthDay out of range');
}
if (newTarget === undefined) {
newTarget = surroundingAgent.intrinsic('%Temporal.PlainMonthDay%');
}
const object = Q(yield* OrdinaryCreateFromConstructor(newTarget, '%Temporal.PlainMonthDay.prototype%', [
'InitializedTemporalMonthDay',
'ISODate',
'Calendar',
])) as Mutable<TemporalPlainMonthDayObject>;
object.ISODate = isoDate;
object.Calendar = calendar;
return object;
}
/** https://tc39.es/proposal-temporal/#sec-temporal-temporalmonthdaytostring */
export function TemporalMonthDayToString(
monthDay: TemporalPlainMonthDayObject,
showCalendar: 'auto' | 'always' | 'never' | 'critical',
): string {
const month = ToZeroPaddedDecimalString(monthDay.ISODate.Month, 2);
const day = ToZeroPaddedDecimalString(monthDay.ISODate.Day, 2);
let result = `${month}-${day}`;
if ((showCalendar === 'always' || showCalendar === 'critical') || monthDay.Calendar !== 'iso8601') {
const year = PadISOYear(monthDay.ISODate.Year);
result = `${year}-${result}`;
}
const calendarString = FormatCalendarAnnotation(monthDay.Calendar, showCalendar);
return result + calendarString;
}