Skip to content

Commit

Permalink
Normative: Remove support for nested calendar property bags
Browse files Browse the repository at this point in the history
Previously, "nested" calendar property bags were unwrapped up to one
level. That is, this object:
{
  calendar: {
     // ...Temporal.Calendar methods
  }
}
would not be considered to implement the Calendar protocol, but would have
its calendar property used instead, if it were passed to an API that
required a Calendar protocol object.

These nested property bags are no longer supported. Discussion:
tc39#2104 (comment)

See: tc39#2104
  • Loading branch information
ptomato committed Apr 10, 2023
1 parent 1b09799 commit f431988
Show file tree
Hide file tree
Showing 4 changed files with 4 additions and 23 deletions.
1 change: 0 additions & 1 deletion docs/calendar.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,6 @@ The object must implement all of the `Temporal.Calendar` properties and methods
Any object with the required methods will return the correct output from any Temporal property or method.
However, most other code will assume that custom calendars act like built-in `Temporal.Calendar` objects.
To interoperate with libraries or other code that you didn't write, then you should implement the `fields()`, `mergeFields()`, `toString()`, and `toJSON()` methods as well.
Your object must not have a `calendar` property, so that it can be distinguished in `Temporal.Calendar.from()` from other Temporal objects that have a calendar.

The identifier of a custom calendar must consist of one or more components of between 3 and 8 ASCII alphanumeric characters each, separated by dashes, as described in [Unicode Technical Standard 35](https://unicode.org/reports/tr35/tr35.html#Unicode_locale_identifier).

Expand Down
5 changes: 2 additions & 3 deletions polyfill/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -614,7 +614,6 @@ export namespace Temporal {

export interface CalendarProtocol {
id: string;
calendar?: never;
year(date: Temporal.PlainDate | Temporal.PlainDateTime | Temporal.PlainYearMonth | PlainDateLike | string): number;
month(
date:
Expand Down Expand Up @@ -681,7 +680,7 @@ export namespace Temporal {
toJSON?(): string;
}

export type CalendarLike = CalendarProtocol | string | { calendar: CalendarProtocol | string };
export type CalendarLike = CalendarProtocol | string;

/**
* A `Temporal.Calendar` is a representation of a calendar system. It includes
Expand All @@ -691,7 +690,7 @@ export namespace Temporal {
*
* See https://tc39.es/proposal-temporal/docs/calendar.html for more details.
*/
export class Calendar implements Omit<Required<CalendarProtocol>, 'calendar'> {
export class Calendar implements CalendarProtocol {
static from(item: CalendarLike): Temporal.Calendar | CalendarProtocol;
constructor(calendarIdentifier: string);
readonly id: string;
Expand Down
13 changes: 1 addition & 12 deletions polyfill/lib/ecmascript.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -1850,25 +1850,14 @@ export const ES = ObjectAssign({}, ES2022, {

ToTemporalCalendarSlotValue: (calendarLike) => {
if (ES.Type(calendarLike) === 'Object') {
if (ES.IsTemporalCalendar(calendarLike)) return calendarLike;
if (HasSlot(calendarLike, CALENDAR)) return GetSlot(calendarLike, CALENDAR);
if (ES.IsTemporalTime(calendarLike)) {
throw new RangeError('Expected a calendar object but received a Temporal.PlainTime');
}
if (ES.IsTemporalTimeZone(calendarLike)) {
throw new RangeError('Expected a calendar object but received a Temporal.TimeZone');
}
if (!('calendar' in calendarLike)) return calendarLike;
calendarLike = calendarLike.calendar;
if (ES.Type(calendarLike) === 'Object') {
if (ES.IsTemporalTime(calendarLike)) {
throw new RangeError('Expected a calendar object as the calendar property but received a Temporal.PlainTime');
}
if (ES.IsTemporalTimeZone(calendarLike)) {
throw new RangeError('Expected a calendar object as the calendar property but received a Temporal.TimeZone');
}
if (!('calendar' in calendarLike)) return calendarLike;
}
return calendarLike;
}
const identifier = ES.ToString(calendarLike);
if (ES.IsBuiltinCalendar(identifier)) return ES.ASCIILowercase(identifier);
Expand Down
8 changes: 1 addition & 7 deletions spec/calendar.html
Original file line number Diff line number Diff line change
Expand Up @@ -497,16 +497,10 @@ <h1>
1. Assert: IsBuiltinCalendar(_default_) is *true*.
1. Return _default_.
1. If Type(_temporalCalendarLike_) is Object, then
1. If _temporalCalendarLike_ has an [[InitializedTemporalCalendar]] internal slot, then
1. Return _temporalCalendarLike_.
1. If _temporalCalendarLike_ has an [[InitializedTemporalDate]], [[InitializedTemporalDateTime]], [[InitializedTemporalMonthDay]], [[InitializedTemporalYearMonth]], or [[InitializedTemporalZonedDateTime]] internal slot, then
1. Return _temporalCalendarLike_.[[Calendar]].
1. If _temporalCalendarLike_ has an [[InitializedTemporalTime]] or [[InitializedTemporalTimeZone]] internal slot, throw a *RangeError* exception.
1. If ? HasProperty(_temporalCalendarLike_, *"calendar"*) is *false*, return _temporalCalendarLike_.
1. Set _temporalCalendarLike_ to ? Get(_temporalCalendarLike_, *"calendar"*).
1. If Type(_temporalCalendarLike_) is Object, then
1. If _temporalCalendarLike_ has an [[InitializedTemporalTime]] or [[InitializedTemporalTimeZone]] internal slot, throw a *RangeError* exception.
1. If ? HasProperty(_temporalCalendarLike_, *"calendar"*) is *false*, return _temporalCalendarLike_.
1. Return _temporalCalendarLike_.
1. Let _identifier_ be ? ToString(_temporalCalendarLike_).
1. Set _identifier_ to ? ParseTemporalCalendarString(_identifier_).
1. If IsBuiltinCalendar(_identifier_) is *false*, throw a *RangeError* exception.
Expand Down

0 comments on commit f431988

Please sign in to comment.