mirror of
https://github.com/bendtherules/ask262.git
synced 2026-08-18 13:21:55 +00:00
86 lines
4.2 KiB
TypeScript
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;
|
|
}
|