Support for the Nepali calendar is currently not built in to JS environments. This example shows how to implement a custom calendar with Temporal, by creating a date class for that calendar that works like PlainDate and can be used as a PlainDate property bag.
/**
* This implementation is based on World-Calendars library by Keith Wood:
* https://github.com/kbwood/world-calendars
* And multi-calendar-dates which originally implemented a custom Temporal.Calendar:
* https://github.com/dhis2/multi-calendar-dates/blob/main/src/custom-calendars/nepaliCalendar.ts
*/
/**
* First, some data for the Nepali calendar. (Just scroll past this.)
*
* - The key (1970...) is the Nepali year.
* - The first colummn is what day the year starts in Paush.
* - The year always starts in Paush (the 9th month) but it is somewhere
* between 17 to 19th of Paush.
* - The other 12 columns show how many days are in each month.
*
* The data goes from 1970 (1913 in ISO calendar) to 2100 (2044 in ISO.) It's an
* abbreviated range, a real calendar implementation should have more data.
*/
var NEPALI_CALENDAR_DATA = {
// These data are from http://www.ashesh.com.np
1970: [18, 31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
1971: [18, 31, 31, 32, 31, 32, 30, 30, 29, 30, 29, 30, 30],
1972: [17, 31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 30],
1973: [19, 30, 32, 31, 32, 31, 30, 30, 30, 29, 30, 29, 31],
1974: [19, 31, 31, 32, 30, 31, 31, 30, 29, 30, 29, 30, 30],
1975: [18, 31, 31, 32, 32, 30, 31, 30, 29, 30, 29, 30, 30],
1976: [17, 31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31],
1977: [18, 31, 32, 31, 32, 31, 31, 29, 30, 29, 30, 29, 31],
1978: [18, 31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
1979: [18, 31, 31, 32, 32, 31, 30, 30, 29, 30, 29, 30, 30],
1980: [17, 31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31],
1981: [18, 31, 31, 31, 32, 31, 31, 29, 30, 30, 29, 30, 30],
1982: [18, 31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
1983: [18, 31, 31, 32, 32, 31, 30, 30, 29, 30, 29, 30, 30],
1984: [17, 31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31],
1985: [18, 31, 31, 31, 32, 31, 31, 29, 30, 30, 29, 30, 30],
1986: [18, 31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
1987: [18, 31, 32, 31, 32, 31, 30, 30, 29, 30, 29, 30, 30],
1988: [17, 31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31],
1989: [18, 31, 31, 31, 32, 31, 31, 30, 29, 30, 29, 30, 30],
1990: [18, 31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
1991: [18, 31, 32, 31, 32, 31, 30, 30, 29, 30, 29, 30, 30],
// These data are from http://nepalicalendar.rat32.com/index.php
1992: [17, 31, 32, 31, 32, 31, 30, 30, 30, 29, 30, 29, 31],
1993: [18, 31, 31, 31, 32, 31, 31, 30, 29, 30, 29, 30, 30],
1994: [18, 31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
1995: [17, 31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 30],
1996: [17, 31, 32, 31, 32, 31, 30, 30, 30, 29, 30, 29, 31],
1997: [18, 31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
1998: [18, 31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
1999: [17, 31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31],
2000: [17, 30, 32, 31, 32, 31, 30, 30, 30, 29, 30, 29, 31],
2001: [18, 31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
2002: [18, 31, 31, 32, 32, 31, 30, 30, 29, 30, 29, 30, 30],
2003: [17, 31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31],
2004: [17, 30, 32, 31, 32, 31, 30, 30, 30, 29, 30, 29, 31],
2005: [18, 31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
2006: [18, 31, 31, 32, 32, 31, 30, 30, 29, 30, 29, 30, 30],
2007: [17, 31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31],
2008: [17, 31, 31, 31, 32, 31, 31, 29, 30, 30, 29, 29, 31],
2009: [18, 31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
2010: [18, 31, 31, 32, 32, 31, 30, 30, 29, 30, 29, 30, 30],
2011: [17, 31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31],
2012: [17, 31, 31, 31, 32, 31, 31, 29, 30, 30, 29, 30, 30],
2013: [18, 31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
2014: [18, 31, 31, 32, 32, 31, 30, 30, 29, 30, 29, 30, 30],
2015: [17, 31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31],
2016: [17, 31, 31, 31, 32, 31, 31, 29, 30, 30, 29, 30, 30],
2017: [18, 31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
2018: [18, 31, 32, 31, 32, 31, 30, 30, 29, 30, 29, 30, 30],
2019: [17, 31, 32, 31, 32, 31, 30, 30, 30, 29, 30, 29, 31],
2020: [17, 31, 31, 31, 32, 31, 31, 30, 29, 30, 29, 30, 30],
2021: [18, 31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
2022: [17, 31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 30],
2023: [17, 31, 32, 31, 32, 31, 30, 30, 30, 29, 30, 29, 31],
2024: [17, 31, 31, 31, 32, 31, 31, 30, 29, 30, 29, 30, 30],
2025: [18, 31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
2026: [17, 31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31],
2027: [17, 30, 32, 31, 32, 31, 30, 30, 30, 29, 30, 29, 31],
2028: [17, 31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
2029: [18, 31, 31, 32, 31, 32, 30, 30, 29, 30, 29, 30, 30],
2030: [17, 31, 32, 31, 32, 31, 30, 30, 30, 30, 30, 30, 31],
2031: [17, 31, 32, 31, 32, 31, 31, 31, 31, 31, 31, 31, 31],
2032: [17, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32],
2033: [18, 31, 31, 32, 32, 31, 30, 30, 29, 30, 29, 30, 30],
2034: [17, 31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31],
2035: [17, 30, 32, 31, 32, 31, 31, 29, 30, 30, 29, 29, 31],
2036: [17, 31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
2037: [18, 31, 31, 32, 32, 31, 30, 30, 29, 30, 29, 30, 30],
2038: [17, 31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31],
2039: [17, 31, 31, 31, 32, 31, 31, 29, 30, 30, 29, 30, 30],
2040: [17, 31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
2041: [18, 31, 31, 32, 32, 31, 30, 30, 29, 30, 29, 30, 30],
2042: [17, 31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31],
2043: [17, 31, 31, 31, 32, 31, 31, 29, 30, 30, 29, 30, 30],
2044: [17, 31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
2045: [18, 31, 32, 31, 32, 31, 30, 30, 29, 30, 29, 30, 30],
2046: [17, 31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31],
2047: [17, 31, 31, 31, 32, 31, 31, 30, 29, 30, 29, 30, 30],
2048: [17, 31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
2049: [17, 31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 30],
2050: [17, 31, 32, 31, 32, 31, 30, 30, 30, 29, 30, 29, 31],
2051: [17, 31, 31, 31, 32, 31, 31, 30, 29, 30, 29, 30, 30],
2052: [17, 31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
2053: [17, 31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 30],
2054: [17, 31, 32, 31, 32, 31, 30, 30, 30, 29, 30, 29, 31],
2055: [17, 31, 31, 32, 31, 31, 31, 30, 29, 30, 30, 29, 30],
2056: [17, 31, 31, 32, 31, 32, 30, 30, 29, 30, 29, 30, 30],
2057: [17, 31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31],
2058: [17, 30, 32, 31, 32, 31, 30, 30, 30, 29, 30, 29, 31],
2059: [17, 31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
2060: [17, 31, 31, 32, 32, 31, 30, 30, 29, 30, 29, 30, 30],
2061: [17, 31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31],
2062: [17, 30, 32, 31, 32, 31, 31, 29, 30, 29, 30, 29, 31],
2063: [17, 31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
2064: [17, 31, 31, 32, 32, 31, 30, 30, 29, 30, 29, 30, 30],
2065: [17, 31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31],
2066: [17, 31, 31, 31, 32, 31, 31, 29, 30, 30, 29, 29, 31],
2067: [17, 31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
2068: [17, 31, 31, 32, 32, 31, 30, 30, 29, 30, 29, 30, 30],
2069: [17, 31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31],
2070: [17, 31, 31, 31, 32, 31, 31, 29, 30, 30, 29, 30, 30],
2071: [17, 31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
2072: [17, 31, 32, 31, 32, 31, 30, 30, 29, 30, 29, 30, 30],
2073: [17, 31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31],
2074: [17, 31, 31, 31, 32, 31, 31, 30, 29, 30, 29, 30, 30],
2075: [17, 31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
2076: [16, 31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 30],
2077: [17, 31, 32, 31, 32, 31, 30, 30, 30, 29, 30, 29, 31],
2078: [17, 31, 31, 31, 32, 31, 31, 30, 29, 30, 29, 30, 30],
2079: [17, 31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
2080: [16, 31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 30],
// These data are from http://www.ashesh.com.np/nepali-calendar/
2081: [17, 31, 31, 32, 32, 31, 30, 30, 30, 29, 30, 30, 30],
2082: [17, 31, 32, 31, 32, 31, 30, 30, 30, 29, 30, 30, 30],
2083: [17, 31, 31, 32, 31, 31, 30, 30, 30, 29, 30, 30, 30],
2084: [17, 31, 31, 32, 31, 31, 30, 30, 30, 29, 30, 30, 30],
2085: [17, 31, 32, 31, 32, 31, 31, 30, 30, 29, 30, 30, 30],
2086: [17, 31, 32, 31, 32, 31, 30, 30, 30, 29, 30, 30, 30],
2087: [16, 31, 31, 32, 31, 31, 31, 30, 30, 29, 30, 30, 30],
2088: [16, 30, 31, 32, 32, 30, 31, 30, 30, 29, 30, 30, 30],
2089: [17, 31, 32, 31, 32, 31, 30, 30, 30, 29, 30, 30, 30],
2090: [17, 31, 32, 31, 32, 31, 30, 30, 30, 29, 30, 30, 30],
2091: [16, 31, 31, 32, 31, 31, 31, 30, 30, 29, 30, 30, 30],
2092: [16, 31, 31, 32, 32, 31, 30, 30, 30, 29, 30, 30, 30],
2093: [17, 31, 32, 31, 32, 31, 30, 30, 30, 29, 30, 30, 30],
2094: [17, 31, 31, 32, 31, 31, 30, 30, 30, 29, 30, 30, 30],
2095: [17, 31, 31, 32, 31, 31, 31, 30, 29, 30, 30, 30, 30],
2096: [17, 30, 31, 32, 32, 31, 30, 30, 29, 30, 29, 30, 30],
2097: [17, 31, 32, 31, 32, 31, 30, 30, 30, 29, 30, 30, 30],
2098: [17, 31, 31, 32, 31, 31, 31, 29, 30, 29, 30, 30, 31],
2099: [17, 31, 31, 32, 31, 31, 31, 30, 29, 29, 30, 30, 30],
2100: [17, 31, 32, 31, 32, 30, 31, 30, 29, 30, 29, 30, 30]
};
// Helpers for consuming the months table
const supportedNepaliYears = Object.keys(NEPALI_CALENDAR_DATA);
const firstSupportedNepaliYear = Number(supportedNepaliYears[0]);
const lastSupportedNepaliYear = Number(supportedNepaliYears[supportedNepaliYears.length - 1]);
function getNepaliYearData(nepaliYear) {
if (nepaliYear < firstSupportedNepaliYear || nepaliYear > lastSupportedNepaliYear) {
throw new Error(
`Conversions are only possible between ${firstSupportedNepaliYear}` +
` and ${lastSupportedNepaliYear} in Nepali calendar`
);
}
return NEPALI_CALENDAR_DATA[nepaliYear];
}
class NepaliPlainDate {
#iso; // The underlying Temporal.PlainDate instance, using the ISO calendar
constructor(isoYear, isoMonth, isoDay) {
this.#iso = new Temporal.PlainDate(isoYear, isoMonth, isoDay);
}
get calendarId() {
return 'nepali'; // Note this is not a built-in calendar ID
}
// era and eraYear not implemented; from localization data it looks like there
// is an epoch in the Nepali calendar, but this calendar implementation only
// supports a small range of years anyway.
get year() {
return this.#isoToNepali().year;
}
get month() {
return this.#isoToNepali().month;
}
get monthCode() {
return `M${this.month.toString().padStart(2, '0')}`;
}
get day() {
return this.#isoToNepali().day;
}
// dayOfWeek delegates to Temporal.PlainDate directly. Nepali calendars seem
// to use ISO days of the week, with localized names.
get dayOfWeek() {
return this.#iso.dayOfWeek;
}
get daysInWeek() {
return 7;
}
get dayOfYear() {
const { year, month, day } = this.#isoToNepali();
const yearData = getNepaliYearData(year);
let result = 0;
for (let monthCounter = 1; monthCounter < month; monthCounter++) {
result += yearData[monthCounter];
}
result += day;
return result;
}
get weekOfYear() {
return undefined;
}
get yearOfWeek() {
return undefined;
}
get daysInMonth() {
const { year, month } = this.#isoToNepali();
const yearData = getNepaliYearData(year);
return yearData[month];
}
get daysInYear() {
const yearData = getNepaliYearData(this.year);
let result = 0;
for (let monthCounter = 1; monthCounter <= 12; monthCounter++) {
result += yearData[monthCounter];
}
return result;
}
get monthsInYear() {
return 12;
}
get inLeapYear() {
return this.daysInYear !== 365;
}
// withCalendar delegated to Temporal.PlainDate directly:
withCalendar(calendar) {
return this.#iso.withCalendar(calendar);
}
equals(other) {
return other instanceof NepaliPlainDate && this.#iso.equals(other.#iso);
}
toString({ showCalendar = 'auto', ...options } = {}) {
let result = this.#iso.toString({ ...options, showCalendar: 'never' });
if (showCalendar !== 'never') {
result += '[u-ca=nepali]';
}
return result;
// Note: if [u-ca=nepali] is appended, the string cannot be deserialized.
// You would implement deserialization in from().
}
toJSON() {
return this.#iso.toString({ showCalendar: 'never' }) + '[u-ca=nepali]';
}
// Note: for brevity, deserialization from a string and conversion from
// year-monthCode-day are not implemented.
static from(fields, { overflow = 'constrain' } = {}) {
let { year: nepaliYear, month: nepaliMonth, day: nepaliDay } = fields;
let yearData = getNepaliYearData(nepaliYear);
const maxDay = yearData[nepaliMonth];
if (nepaliDay > maxDay) {
if (overflow === 'reject') {
throw new RangeError(`month ${nepaliMonth} has ${maxDay} days, not ${nepaliDay}`);
}
nepaliDay = maxDay;
}
let isoDayOfYear = 0;
let monthCounter = nepaliMonth;
const isoYear = nepaliYear - (nepaliMonth > 9 || (monthCounter === 9 && nepaliDay >= yearData[0]) ? 56 : 57);
// First we add the amount of days in the actual Nepali month as the day of
// year in the ISO one because at least these days are gone since the 1st Jan.
if (nepaliMonth !== 9) {
isoDayOfYear = nepaliDay;
monthCounter--;
}
// Now we loop through all Nepali months and add the amount of days to
// isoDayOfYear. We do this till we reach Paush (9th month). 1st January
// always falls in this month.
while (monthCounter !== 9) {
if (monthCounter <= 0) {
monthCounter = 12;
nepaliYear--;
yearData = getNepaliYearData(nepaliYear);
}
isoDayOfYear += yearData[monthCounter];
monthCounter--;
}
// If the date that has to be converted is in Paush (month no. 9) we have to
// do some other calculation
if (nepaliMonth === 9) {
// Add the days that are passed since the first day of Paush and substract
// the amount of days that lie between 1st Jan and 1st Paush
isoDayOfYear += nepaliDay - yearData[0];
// For the first days of Paush we are now in negative values, because in the
// end of the ISO year we subtract 365 or 366 days
if (isoDayOfYear < 0) {
isoDayOfYear += new Temporal.PlainDate(isoYear, 1, 1).daysInYear;
}
} else {
isoDayOfYear += yearData[9] - yearData[0];
}
const isoDate = new Temporal.PlainDate(isoYear, 1, 1).add({ days: isoDayOfYear });
return new NepaliPlainDate(isoDate.year, isoDate.month, isoDate.day);
}
// Use this method instead of plainDate.withCalendar('nepali').
static fromTemporalPlainDate(plainDate) {
const iso = plainDate.withCalendar('iso8601');
return new NepaliPlainDate(iso.year, iso.month, iso.day);
}
static compare(one, two) {
return Temporal.PlainDate.compare(one, two);
}
#isoToNepali() {
const isoDayOfYear = this.#iso.dayOfYear;
let nepaliYear = this.#iso.year + 56;
// This is not final, it could be also +57 but +56 is always true for 1st Jan.
let yearData = getNepaliYearData(nepaliYear);
// Jan 1 always falls in Nepali month Paush which is the 9th month of Nepali
// calendar.
let nepaliMonth = 9;
// Get the Nepali day in Paush (month 9) of 1st January
const dayOfFirstJanInPaush = yearData[0];
// Check how many days are left of Paush.
// Days calculated from 1st Jan till the end of the actual Nepali month,
// we use this value to check if the ISO date is in the actual Nepali month.
let daysSinceJanFirstToEndOfNepaliMonth = yearData[nepaliMonth] - dayOfFirstJanInPaush + 1;
// If the Gregorian day-of-year is smaller than or equal to the sum of days
// between the 1st January and the end of the actual Nepali month we have
// found the correct Nepali month.
// Example:
// The 4th February 2011 is the isoDayOfYear 35 (31 days of January + 4)
// 1st January 2011 is in the Nepali year 2067, where 1st January is the
// 17th day of Paush (9th month).
// In 2067 Paush has 30 days, which means (30-17+1=14) there are 14 days
// between 1st January and end of Paush (including 17th January).
// The isoDayOfYear (35) is bigger than 14, so we check the next month.
// The next Nepali month (Mangh) has 29 days
// 29+14=43, this is bigger than isoDayOfYear (35) so, we have found the
// correct Nepali month.
while (isoDayOfYear > daysSinceJanFirstToEndOfNepaliMonth) {
nepaliMonth++;
if (nepaliMonth > 12) {
nepaliMonth = 1;
nepaliYear++;
yearData = getNepaliYearData(nepaliYear);
}
daysSinceJanFirstToEndOfNepaliMonth += yearData[nepaliMonth];
}
// The last step is to calculate the Nepali day-of-month.
// To continue our example from before:
// we calculated there are 43 days from 1st January (17 Paush) till end of
// Mangh (29 days). When we subtract from this 43 days the day-of-year of
// the ISO date (35), we know how far the searched day is away from the end
// of the Nepali month. So we simply subtract this number from the amount of
// days in this month (30).
const nepaliDayOfMonth = yearData[nepaliMonth] - (daysSinceJanFirstToEndOfNepaliMonth - isoDayOfYear);
return { year: nepaliYear, month: nepaliMonth, day: nepaliDayOfMonth };
}
// Some methods omitted for brevity:
// with() could be implemented without too much trouble, but resolving the
// month/monthCode pair takes up a lot of space without being really relevant
// to this example
with(dateLike, { overflow = 'constrain' } = {}) {
void this.#iso.with(dateLike, { overflow });
throw new Error('not implemented');
}
// toLocaleString() is omitted because I don't know how to localize dates in
// this calendar
toLocaleString(locales = undefined, options = undefined) {
void locales, options;
throw new Error('unimplemented');
}
// The conversion methods are omitted. They could be made to work by
// implementing NepaliPlainDateTime, etc. It depends on your use case whether
// you would need this or not.
toPlainDateTime(plainTime) {
void plainTime;
throw new Error('unimplemented');
}
toZonedDateTime(options) {
void options;
throw new Error('unimplemented');
}
toPlainYearMonth() {
throw new Error('unimplemented');
}
toPlainMonthDay() {
throw new Error('unimplemented');
}
// The arithmetic methods are omitted. World-Calendars doesn't have date
// arithmetic as far as I can tell. These could be made to work by someone
// who is familiar with the conventions of date arithmetic in this calendar.
add(duration, { overflow = 'constrain' } = {}) {
void this.#iso.add(duration, { overflow });
throw new Error('not implemented');
}
subtract(duration, { overflow = 'constrain' } = {}) {
void this.#iso.subtract(duration, { overflow });
throw new Error('not implemented');
}
until(other, { largestUnit = 'day' } = {}) {
void this.#iso.until(other.#iso, { largestUnit });
throw new Error('not implemented');
}
since(other, { largestUnit = 'day' } = {}) {
void this.#iso.since(other.#iso, { largestUnit });
throw new Error('not implemented');
}
}
// Here we run a number of tests, to check that the implementation above makes
// sense.
const n = NepaliPlainDate.from({ year: 2081, month: 3, day: 11 });
assert.equal(n.toString(), '2024-06-24[u-ca=nepali]');
assert.equal(n.era, undefined);
assert.equal(n.eraYear, undefined);
assert.equal(n.year, 2081);
assert.equal(n.month, 3);
assert.equal(n.monthCode, 'M03');
assert.equal(n.day, 11);
assert.equal(n.dayOfWeek, 1);
assert.equal(n.daysInWeek, 7);
assert.equal(n.weekOfYear, undefined);
assert.equal(n.yearOfWeek, undefined);
assert.equal(n.daysInMonth, 32);
assert.equal(n.daysInYear, 366);
assert.equal(n.monthsInYear, 12);
assert.equal(n.inLeapYear, true);
const withBuiltinCalendar = n.withCalendar('gregory');
assert.equal(withBuiltinCalendar.toString(), '2024-06-24[u-ca=gregory]');
assert(withBuiltinCalendar instanceof Temporal.PlainDate, 'withCalendar returns real PlainDate');
assert(n.equals(n), 'equals self');
assert(n.equals(NepaliPlainDate.from(n)), 'equals new instance of self');
assert(!n.equals(withBuiltinCalendar), 'does not equal real PlainDate');
assert.equal(n.toJSON(), '2024-06-24[u-ca=nepali]');