Javascript temporal calendar

Temporal.Calendar

A Calendar API is under discussion. See Calendar Draft for more information.

Draft Design of Temporal Calendar API

This doc describes a design for first-class support for non-Gregorian calendars in Temporal.

Although most of this document is based on Temporal.Date, most of this applies to Temporal.DateTime, Temporal.YearMonth, Temporal.MonthDay, and Temporal.Time as well.

Temporal.Calendar interface

Main issue: https://github.com/tc39/proposal-temporal/issues/289

The new Temporal.Calendar interface is a mechanism to allow arbitrary calendar systems to be implemented on top of Temporal.

Most users will not encounter the Temporal.Calendar interface directly, unless they are building or using a non-built-in calendar system.

All built-in calendars will be instances of Temporal.Calendar (main issue: #300), and Temporal.Calendar can be subclassed.

However, an object need not be a subclass of Temporal.Calendar to conform to the interface, which are the string methods listed below.

We had also considered using symbols, but settled on strings after discussion with the plenary (main issue: #310).

Default Calendar

Main issue: https://github.com/tc39/proposal-temporal/issues/292

An open question is what the behavior should be if the programmer does not specify a calendar, or if we should require the programmer to always specify a calendar. Four choices are on the table:

  • Default to full ISO (Gregorian) calendar.

  • Require the user to explicitly specify the calendar.

  • Default to a partial ISO calendar (explained below).

  • Default to Intl.defaultCalendar (a new symbol), or ISO if that field doesn’t exist.

To enable the extended set of operations, the user would just use .withCalendar():

// Force the Gregorian calendar:
Temporal.Date.from("2019-12-06").withCalendar("gregory").weekOfYear;

// Use a calendar from another source:
Temporal.Date.from("2019-12-06").withCalendar(Intl.defaultCalendar).weekOfYear;
Temporal.Date.from("2019-12-06").withCalendar(request.calendar).weekOfYear;

The calendar IDs are less clear. If the partial ISO calendar used ID “iso”, then what would the full ISO calendar use? ID “gregory” (why not “gregorian”?) is misleading because there are Gregorian calendars that do not all agree on the same rules for things like weeks of the year.

One solution could be to use a nullish ID like null or “” for the partial ISO calendar and “iso” for the full ISO calendar.

Alternatively, “iso8601”, the identifier defined by CLDR as “Gregorian calendar using the ISO 8601 calendar week rules”, could be the identifier for the full ISO calendar.

Temporal.Date API changes

New Temporal.Date instance methods

Temporal.Date.prototype.with does not modify the calendar.

A new method is added for that

Temporal.Date.prototype.withCalendar = function(newCalendar: Calendar): Temporal.Date {
    const { year, month, day } = this.getISOFields();
    // note: call intrinsic version
    return new Temporal.Date(year, month, day, newCalendar);
    // note: use species constructor
}