This specification identifies calendars using a calendar type as defined by Unicode Technical Standard #35 Part 4 Dates, Section 2 Calendar Elements. Their canonical form is a string containing only Unicode Basic Latin lowercase letters (U+0061 LATIN SMALL LETTER A through U+007A LATIN SMALL LETTER Z) with zero or more medial hyphens (U+002D HYPHEN-MINUS).
ECMA-262 describes calendar types, of which "iso8601" is required to be supported.
This specification additionally requires ECMAScript implementations to support calendar types corresponding with those of the Unicode Common Locale Data Repository (CLDR).
1.1.1 AvailableCalendars ( )
The implementation-defined abstract operation AvailableCalendars takes no arguments and returns a List of calendar types. The returned List is sorted according to lexicographic code unit order, and contains unique calendar types in canonical form (6.9) identifying the calendars for which the implementation provides the functionality of Intl.DateTimeFormat objects, including their aliases (e.g., either both or neither of"islamicc" and "islamic-civil"). The List must include "iso8601"the Calendar Type value of every row of Table 1, except the header row.
This definition supersedes the definition provided in 6.9.1.
Thai Buddhist calendar, proleptic. Month numbers, month codes, and days are the same as in the ISO 8601 calendar, but the epoch year is different. There is one era.
"chinese"
Traditional Chinese calendar, proleptic. Lunisolar calendar using months based on GB/T 33661-2017 between 1900 and 2100, falling back to an implementation-defined approximation outside that range. The arithmetic year is identical to "gregory", and there are no eras.
"coptic"
Coptic calendar, proleptic. Similar solar algorithm to "ethioaa" and "ethiopic", with one era and a different epoch year.
"dangi"
Traditional Korean calendar, proleptic. Lunisolar calendar using months published by the Korea Astronomy and Space Science Institute (KASI) between 1900 and 2050, falling back to an implementation-defined approximation outside that range. The arithmetic year is identical to "gregory", and there are no eras.
"ethioaa"
Ethiopic calendar, Amete Alem, proleptic. Similar solar algorithm to "coptic" and "ethiopic", with one era and a different epoch year.
"ethiopic"
Ethiopic calendar, Amete Mihret, proleptic. Similar solar algorithm to "coptic" and "ethioaa", with two eras and a different epoch year.
"ethiopic-amete-alem"
Alias for "ethioaa".
"gregory"
Gregorian calendar, proleptic. Solar calendar almost identical to the ISO 8601 calendar, except that it does not define week numbering and it contains two eras, one before the epoch year.
"hebrew"
Hebrew calendar, proleptic. Civil calendar with Tishrei as the first month of the year. Lunisolar calendar with one leap month inserted after month 5. There is one era.
"indian"
Indian national (or Śaka) calendar, proleptic. Solar calendar with one era.
"islamic-civil"
Hijri calendar, proleptic, tabular/rule-based with leap years 2, 5, 7, 10, 13, 16, 18, 21, 24, 26, 29 in the 30-year cycle, and civil epoch (Friday July 16, 622 Julian / 0622-07-19 ISO)
"islamic-tbla"
Hijri calendar, proleptic, tabular/rule-based with leap years 2, 5, 7, 10, 13, 16, 18, 21, 24, 26, 29 in the 30-year cycle, and astronomical epoch (Thursday July 15, 622 Julian / 0622-07-18 ISO)
"islamic-umalqura"
Hijri calendar, proleptic, Umm al-Qura. Lunar calendar using KACST-calculated months from the start of 1300 AH to the end of 1600 AH, falling back to "islamic-civil" outside that range.
Japanese Imperial calendar, era system hybridised with "gregory". Month numbers, month codes, and days are the same as in the ISO 8601 calendar, extended proleptically before their introduction in ISO year 1873. Imperial era names only extend as far back as the Meiji period (starting in ISO year 1868) during which calendar reforms took place. The arithmetic year, and the years and eras before ISO year 1868, are identical to "gregory".
"persian"
Persian (or Solar Hijri) calendar, proleptic. There is one era.
"roc"
Republic of China (or Minguo) calendar, proleptic. Month numbers, month codes, and days are the same as in the ISO 8601 calendar, but the epoch year is different. There are two eras, one before the epoch year and one after.
2 Locale and Parameter Negotiation
2.1 Internal slots of Service Constructors
[...]
Note
For example, an implementation of DateTimeFormat might include the language tag"fa-IR" in its [[AvailableLocales]] internal slot, and must (according to 11.2.3) include the keys "ca", "hc", and "nu" in its [[RelevantExtensionKeys]] internal slot.
The default calendar for that locale is usually "persian", but an implementation might also support "gregory", "islamic", and "islamic-civil".
The Record in the DateTimeFormat [[LocaleData]] internal slot would therefore include a [[fa-IR]] field whose value is a Record like { [[ca]]: « "persian", "gregory", "islamic","islamic-civil" », [[hc]]: « … », [[nu]]: « … » }, along with other locale-named fields having the same value shape but different elements in their Lists.
If the ECMAScript implementation has a mechanism for reporting diagnostic warning messages, a warning should be issued.
Set dateTimeFormat.[[Calendar]] to resolvedCalendar.
NOTE: Rest of algorithm unchanged.
3.2 Properties of the Intl.DateTimeFormat Constructor
3.2.1 Internal slots
[...]
The value of the [[LocaleData]] internal slot is implementation-defined within the constraints described in 2.1 and the following additional constraints, for all locale values locale:
[[LocaleData]].[[<locale>]].[[ca]] must be a List consisting of values from the Calendar Type column of Table 1. The list may also include "islamic" and "islamic-rgsa".
[[LocaleData]].[[<locale>]].[[nu]] must be a List that does not include the values "native", "traditio", or "finance".
[[LocaleData]].[[<locale>]].[[hc]] must be « null, "h11", "h12", "h23", "h24" ».
[...]
4 Locale Sensitive Functions of the ECMAScript Language Specification
4.1 Abstract Operations for Calendar Calculations
4.1.1 CalendarSupportsEra ( calendar )
The abstract operation CalendarSupportsEra takes argument calendar (a calendar type) and returns a Boolean.
The following algorithm refers to the era data from UTS 35's Supplemental Calendar Data.
It performs the following steps when called:
If calendar is listed in the Calendar column of Table 2, return true.
Return false.
Table 2 lists all possible eras for the current set of calendars, including their aliases, ranges and kinds.
The era kind is used by CalendarDateArithmeticYearForEraYear to calculate arithmetic year ([[Year]]):
An Era kindepoch means that the era is the epoch era, so 1 Era has an arithmetic year of 1. An Era kindnegative means that the era is a "negative" era growing
from the epoch, so 1 Era is an arithmetic year of 0, and larger [[EraYear]] values produce smaller, negative arithmetic years. An Era kind of
offset means that the era is "offset" by a given number (in the Offset column), so 1 Era has an arithmetic year of Offset.
Table 2: era aliases, range of eraYear, and era kinds
Calendar
Era
Aliases
Minimum eraYear
Maximum eraYear
Era kind
Offset
"buddhist"
"be"
-∞
+∞
epoch
"coptic"
"am"
-∞
+∞
epoch
"ethioaa"
"aa"
"mundi"
-∞
+∞
epoch
"ethiopic"
"am"
"incar"
1
+∞
epoch
"ethiopic"
"aa"
"mundi"
-∞
5500
offset
-5499
"gregory"
"ce"
"ad"
1
+∞
epoch
"gregory"
"bce"
"bc"
1
+∞
negative
"hebrew"
"am"
-∞
+∞
epoch
"indian"
"shaka"
-∞
+∞
epoch
"islamic-civil"
"ah"
1
+∞
epoch
"islamic-civil"
"bh"
1
+∞
negative
"islamic-tbla"
"ah"
1
+∞
epoch
"islamic-tbla"
"bh"
1
+∞
negative
"islamic-umalqura"
"ah"
1
+∞
epoch
"islamic-umalqura"
"bh"
1
+∞
negative
"japanese"
"reiwa"
1
+∞
offset
2019
"japanese"
"heisei"
1
31
offset
1989
"japanese"
"showa"
1
64
offset
1926
"japanese"
"taisho"
1
15
offset
1912
"japanese"
"meiji"
1
45
offset
1868
"japanese"
"ce"
"ad"
1
1868
epoch
"japanese"
"bce"
"bc"
1
+∞
negative
"persian"
"ap"
-∞
+∞
epoch
"roc"
"roc"
"minguo"
1
+∞
epoch
"roc"
"broc"
"before-roc", "minguo-qian"
1
+∞
negative
4.1.2 CanonicalizeEraInCalendar ( calendar, era )
The abstract operation CanonicalizeEraInCalendar takes arguments calendar (a calendar type that is not "iso8601") and era (a String) and returns a String or undefined.
The following algorithm refers to the era data from UTS 35's Supplemental Calendar Data.
It performs the following steps when called:
Let canonicalName be the Era value of the current row.
If canonicalName is equal to era, return canonicalName.
Let aliases be a List whose elements are the strings given in the Aliases column of the row.
If aliases contains era, return canonicalName.
Return undefined.
4.1.3 IsValidMonthCodeForCalendar ( calendar, monthCode )
The abstract operation IsValidMonthCodeForCalendar takes arguments calendar (a calendar type that is not "iso8601") and monthCode (a String) and returns a Boolean. It performs the following steps when called:
Let commonMonthCodes be « "M01", "M02", "M03", "M04", "M05", "M06", "M07", "M08", "M09", "M10", "M11", "M12" ».
If commonMonthCodes contains monthCode, return true.
If calendar is not listed in the Calendar column of Table 3, return false.
Let r be the row in Table 3 which the calendar is in the Calendar column.
Let specialMonthCodes be a List whose elements are the strings given in the "Additional Month Codes" column of r.
If specialMonthCodes contains monthCode, return true.
4.1.4 IsValidEraYearForCalendar ( calendar, era, eraYear )
The abstract operation IsValidEraYearForCalendar takes arguments calendar (a calendar type that is not "iso8601"), era (a String), and eraYear (an integer) and returns a Boolean.
The following algorithm refers to the era data from UTS 35's Supplemental Calendar Data.
It performs the following steps when called:
Let r be the row in Table 2 in which calendar is in the Calendar column and era is in the Era column.
Let min be the value given in the "Minimum eraYear" column of r.
Let max be the value given in the "Maximum eraYear" column of r.
If eraYear < min, return false.
If eraYear > max, return false.
Return true.
4.1.5 CalendarDateEra ( calendar, date )
The abstract operation CalendarDateEra takes arguments calendar (a calendar type that is not "iso8601") and date (a Temporal.PlainDateTime, Temporal.PlainDate, or Temporal.PlainYearMonth) and returns a String or undefined. It performs implementation-defined processing to find the era for the date corresponding to date in the context of the calendar represented by calendar and returns a lowercase String value representing that era, or undefined for calendars that do not have eras. It performs the following steps when called:
Let era be the String to indicate the era corresponding to date in the context of the calendar represented by calendar according to implementation-defined processing.
The abstract operation CalendarDateEraYear takes arguments calendar (a calendar type that is not "iso8601") and date (a Temporal.PlainDateTime, Temporal.PlainDate, or Temporal.PlainYearMonth) and returns an integer or undefined. It performs implementation-defined processing to find the era for the date corresponding to date in the context of the calendar represented by calendar and returns an integer representing the ordinal position of the year of date in that era, or undefined for calendars that do not have eras. It performs the following steps when called:
Let eraYear be the integer to indicate the era year corresponding to date in the context of the calendar represented by calendar according to implementation-defined processing.
4.1.7 CalendarDateArithmeticYear ( calendar, date )
The abstract operation CalendarDateArithmeticYear takes arguments calendar (a calendar type that is not "iso8601") and date (an ISO Date Record, Temporal.PlainDateTime, Temporal.PlainDate, or Temporal.PlainYearMonth) and returns an integer. It performs implementation-defined processing to find the year for the date corresponding to date in the context of the calendar represented by calendar relative to a well-defined epoch year for that calendar. It performs the following steps when called:
Let r be the row in Table 4 which the value of the Calendar column is calendar.
Let epochYear be the value given in the "Epoch ISO Year" column of r.
Let epochDate be the first day of the calendar year starting in ISO year epochYear in the calendar represented by calendar, according to implementation-defined processing.
Let newYear be the first day of the calendar year of date in the calendar represented by calendar, according to implementation-defined processing.
Let arithmeticYear be the number of whole years between epochDate and newYear in the calendar represented by calendar, according to implementation-defined processing.
Return arithmeticYear.
Table 4: epoch years
Calendar
Epoch ISO Year
"buddhist"
-543
"chinese"
0
"coptic"
283
"dangi"
0
"ethioaa"
-5493
"ethiopic"
7
"gregory"
0
"hebrew"
-3761
"indian"
78
"islamic-civil"
621
"islamic-tbla"
621
"islamic-umalqura"
621
"japanese"
0
"persian"
621
"roc"
1911
4.1.8 CalendarDateArithmeticYearForEraYear ( calendar, era, eraYear )
The abstract operation CalendarDateArithmeticYearForEraYear takes arguments calendar (a calendar type that has eras), era (a String), and eraYear (an integer) and returns an integer. It produces the year relative to the epoch year (the arithmetic year) for a given set of era, eraYear for a calendar that has eras. It performs the following steps when called:
A Calendar Date Record is a Record value used to represent a valid calendar date in a non-ISO 8601 calendar.
Calendar Date Records are produced by the abstract operation CalendarISOToDate.
Calendar Date Records have the fields listed in Table 5.
A lowercase String value representing the date's era, or undefined for calendars that do not have eras.
The value of this field for a calendar typecalendar should be the result of calling CalendarDateEra(calendar, date), where date is a Temporal.PlainDateTime, Temporal.PlainDate, or Temporal.PlainYearMonth value corresponding to the date.
The ordinal position of the date's year within its era, or undefined for calendars that do not have eras.
The value of this field for a calendar typecalendar should be the result of calling CalendarDateEraYear(calendar, date), where date is a Temporal.PlainDateTime, Temporal.PlainDate, or Temporal.PlainYearMonth value corresponding to the date.
Note 1
Era years are 1-indexed for many calendars, but not all (e.g., the eras of the Burmese calendar, not currently available in CLDR, each start with a year 0). Years can also advance opposite the flow of time (as for BCE years in the Gregorian calendar).
The date's year relative to the first day of a calendar-specific "epoch year".
The value of this field for a calendar typecalendar should be the result of calling CalendarDateArithmeticYear(calendar, date), where date is the [[ISODate]] field of a Temporal.PlainDateTime, Temporal.PlainDate, or Temporal.PlainYearMonth value corresponding to the date.
Note 2
The year is relative to the first day of the calendar's epoch year, so if the epoch era starts in the middle of the year, the year will be the same value before and after the start date of the era.
The 1-based ordinal position of the date's month within its year.
Note 3
When the number of months in a year of the calendar is variable, a different value can be returned for dates that are part of the same month in different years. For example, in the Hebrew calendar, 1 Nisan 5781 is associated with value 7 while 1 Nisan 5782 is associated with value 8 because 5782 is a leap year and Nisan follows the insertion of Adar I.
[[MonthCode]]
a String
The month code of the date's month. The month code for a month that is not a leap month and whose 1-based ordinal position in a common year of the calendar (i.e., a year that is not a leap year) is n should be the string-concatenation of "M" and ToZeroPaddedDecimalString(n, 2), and the month code for a month that is a leap month inserted after a month whose 1-based ordinal position in a common year of the calendar is p should be the string-concatenation of "M", ToZeroPaddedDecimalString(p, 2), and "L".
Note 4
For example, in the Hebrew calendar, the month code of Adar (and Adar II, in leap years) is "M06" and the month code of Adar I (the leap month inserted before Adar II) is "M05L". Theoretically, in a calendar with a leap month at the start of some years, the month code of that month would be "M00L".
The Year-Week Record's [[Year]] field is relative to the first day of a calendar-specific "epoch year", as in the Calendar Date Record's [[Year]] field, not relative to an era as in [[EraYear]].
Usually the Year-Week Record's [[Year]] field will contain the same value as the Calendar Date Record's [[Year]] field, but may contain the previous or next year if the week number in the Year-Week Record's [[Week]] field overlaps two different years.
See also ISOWeekOfYear.
The Year-Week Record contains undefined in [[Week]] and [[Year]] field for calendars that do not have a well-defined week numbering system.
Note 5
Currently, of the calendars supported in this specification, only "iso8601" has a well-defined, locale-independent week numbering system.
For all other calendars, the Year-Week Record fields are undefined.
true if the date falls within a leap year, and false otherwise.
Note 6
A "leap year" is a year that contains more days than other years (for solar or lunar calendars) or more months than other years (for lunisolar calendars like Hebrew or Chinese).
Some calendars, especially lunisolar ones, have further variation in year length that is not represented in the output of this operation (e.g., the Hebrew calendar includes common years with 353, 354, or 355 days and leap years with 383, 384, or 385 days).
4.1.10 NonISODateAdd ( calendar, isoDate, duration, overflow )
The implementation-defined abstract operation NonISODateAdd takes arguments calendar (a calendar type that is not "iso8601"), isoDate (an ISO Date Record), duration (a Date Duration Record), and overflow (constrain or reject) and returns either a normal completion containing an ISO Date Record or a throw completion.
The operation performs implementation-defined processing to add duration to date in the context of the calendar represented by calendar and returns the corresponding day, month and year of the result in the ISO 8601 calendar values as an ISO Date Record.
It may throw a RangeError exception if overflow is reject and the resulting month or day would need to be clamped in order to form a valid date in calendar.
The behaviour is implementation-defined, but all calendars follow the general steps given here, which is a generalization of the precise algorithm specified in CalendarDateAdd for "iso8601".
This definition supersedes the definition provided in Temporal, 12.2.6.
(This step only matters for lunisolar calendars.) If calendarDate.[[MonthCode]] is a leap month that doesn't exist in the year, then:
Set calendarDate to another date according to the cultural conventions of that calendar's users. Of the currently supported calendars: if calendar is "chinese" or "dangi", change calendarDate.[[MonthCode]] to the same month code but without the "L". If calendar is "hebrew", change calendarDate.[[MonthCode]] from "M05L" to "M06".
Update calendarDate.[[Month]] accordingly.
Add duration.[[Months]] to calendarDate, balancing calendarDate if it goes over a year boundary.
If the date described by calendarDate does not exist, then
If overflow is reject, throw a RangeError exception.
If calendarDate.[[MonthCode]] is a valid month code for calendarDate.[[Year]], but the date described by calendarDate does not exist, set calendarDate.[[Day]] to the closest day in the same month. If there are two equally-close dates in the same month, pick the later one.
(This step does not apply to any currently supported calendars.) If the date described by calendarDate still does not exist, set calendarDate to the closest date in the same year. If there are two equally-close dates in that year, pick the later one.
Add duration.[[Weeks]] and duration.[[Days]] to calendarDate, balancing calendarDate if it goes over a month or year boundary.
Let result be ? CalendarDateToISO(calendar, calendarDate, overflow).
The algorithm is implementation-defined, but all calendars follow the general steps given here, which is a generalization of the precise algorithm specified in CalendarDateUntil for "iso8601".
This definition supersedes the definition provided in Temporal, 12.2.8.
It performs the following steps when called:
If largestUnit is year, then
Add (without constraining) as many years as possible to one, in the direction from one to two, without surpassing two. "Surpassing" here (and in all steps below) means to compare years numerically, then month codes lexicographically, then days numerically; if any of them exceed two in the direction from one to two, then two is surpassed.
Constrain one to a real year and month, not taking day into account. This step only matters for lunisolar calendars.
If largestUnit is year or month, then
Add (without constraining) as many months as possible to one without surpassing two.
Constrain one to a real year, month, and day.
If largestUnit is week, add as many weeks as possible to one without surpassing two.
Add as many days as possible to one until it is equal to two.
Return a Date Duration Record of the number of years, months, weeks, and days added.
4.1.12 NonISOCalendarDateToISO ( calendar, fields, overflow )
The implementation-defined abstract operation NonISOCalendarDateToISO takes arguments calendar (a calendar type that is not "iso8601"), fields (a Calendar Fields Record), and overflow (constrain or reject) and returns either a normal completion containing an ISO Date Record or a throw completion.
It performs implementation-defined processing to convert fields, which represents either a date or a year and month in the built-in calendar identified by calendar, to a corresponding representative date in the ISO 8601 calendar, subject to overflow correction specified by overflow.
For reject, values that do not form a valid date cause an exception to be thrown, as described below.
For constrain, values that do not form a valid date are clamped to their respective valid range.
Like RegulateISODate, the operation throws a RangeError exception when overflow is reject and the date described by fields does not exist.
Clamping an invalid date to the correct range when overflow is constrain is a behaviour specific to each calendar other than "iso8601", but all calendars follow this guideline.
This definition supersedes the definition provided in Temporal, 12.2.21.
It performs the following steps when called:
If fields.[[Era]] and fields.[[EraYear]] are not unset and IsValidEraYearForCalendar(calendar, fields.[[Era]], fields.[[EraYear]]) is false, throw a RangeError exception.
If fields.[[MonthCode]] is not unset and IsValidMonthCodeForCalendar(calendar, fields.[[MonthCode]]) is false, throw a RangeError exception.
If overflow is reject, throw a RangeError exception.
(This step only matters for lunisolar calendars.) If fields.[[MonthCode]] is a leap month that doesn't exist in the year, then:
Set fields to another date according to the cultural conventions of that calendar's users. Of the currently supported calendars: if calendar is "chinese" or "dangi", change fields.[[MonthCode]] to the same month code but without the "L". If calendar is "hebrew", change fields.[[MonthCode]] from "M05L" to "M06".
Update fields.[[Month]] accordingly.
If fields.[[MonthCode]] is a valid month code for fields.[[Year]], but the date described by fields does not exist, set fields.[[Day]] to the closest day in the same month. If there are two equally-close dates in the same month, pick the later one.
(This step does not apply to any currently supported calendars.) If the date described by fields still does not exist, set fields to the closest date in the same year. If there are two equally-close dates in that year, pick the later one.
The implementation-defined abstract operation CalendarExtraFields takes arguments calendar (a calendar type) and fields (a List of values from the Enumeration Key column of Table 19) and returns a List of values from the Enumeration Key column of Table 19. It characterizes calendar-specific fields that are relevant for the provided fields in the built-in calendar identified by calendar.
This definition supersedes the definition provided in Temporal, 12.2.27.
It performs the following steps when called:
If fields contains an element equal to year and CalendarSupportsEra(calendar) is true, then
Append era and era-year to fields.
Return fields.
4.1.14 NonISOFieldKeysToIgnore ( calendar, keys )
The implementation-defined abstract operation NonISOFieldKeysToIgnore takes arguments calendar (a calendar type that is not "iso8601") and keys (a List of values from the Enumeration Key column of Table 19) and returns a List of values from the Enumeration Key column of Table 19.
It performs implementation-defined processing to determine which calendar date fields changing any of the fields named in keys can potentially conflict with or invalidate, for the given calendar.
A field always invalidates at least itself.
This definition supersedes the definition provided in Temporal, 12.2.28.
If key is month, append month-code to ignoredKeys.
Else if key is month-code, append month to ignoredKeys.
If key is one of era, era-year, or year and CalendarSupportsEra(calendar) is true, then
Append era, era-year, and year to ignoredKeys.
Else,
Append key to ignoredKeys.
If key is one of day, month, or month-code and calendar is "japanese", then
Append era and era-year to ignoredKeys.
NOTE: While ignoredKeys can have duplicate elements, this is not intended to be meaningful. This specification only checks whether particular keys are or are not members of the list.
All Software contained in this document ("Software") is protected by copyright and is being made available under the "BSD License", included below. This Software may be subject to third party rights (rights from parties other than Ecma International), including patent rights, and no licenses under such third party rights are granted under this license even if the third party concerned is a member of Ecma International. SEE THE ECMA CODE OF CONDUCT IN PATENT MATTERS AVAILABLE AT https://ecma-international.org/memento/codeofconduct.htm FOR INFORMATION REGARDING THE LICENSING OF PATENT CLAIMS THAT ARE REQUIRED TO IMPLEMENT ECMA INTERNATIONAL STANDARDS.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
Neither the name of the authors nor Ecma International may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE ECMA INTERNATIONAL "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ECMA INTERNATIONAL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.