Skip to content
This repository has been archived by the owner on Jan 26, 2022. It is now read-only.

Indexing month names for leap month #55

Closed
sffc opened this issue Oct 16, 2019 · 11 comments
Closed

Indexing month names for leap month #55

sffc opened this issue Oct 16, 2019 · 11 comments
Labels
Later For future version to consider, NOT now.

Comments

@sffc
Copy link
Collaborator

sffc commented Oct 16, 2019

I was talking to @pedberg-icu yesterday about how to index month names for the purpose of the Intl.DisplayNames API. He suggested that it could make sense to add an optional second argument to the .of() method for type: "month" to indicate whether the month is a leap-month. Opening an issue to continue this discussion.

@FrankYFTang FrankYFTang changed the title Indexing month names Indexing month names for leap month Oct 17, 2019
@sffc
Copy link
Collaborator Author

sffc commented Dec 1, 2019

A snag in the Hebrew calendar: the digits used to represent months map to different strings each year. For example:

new Date(2018, 2, 20).toLocaleDateString("en-US-u-ca-hebrew", { month: "long", day: "numeric" })
"Nisan 4"
new Date(2019, 2, 20).toLocaleDateString("en-US-u-ca-hebrew", { month: "long", day: "numeric" })
"Adar II 13"
new Date(2018, 2, 20).toLocaleDateString("en-US-u-ca-hebrew", { month: "numeric", day: "numeric" })
"7/4"
new Date(2019, 2, 20).toLocaleDateString("en-US-u-ca-hebrew", { month: "numeric", day: "numeric" })
"7/13"

@sffc
Copy link
Collaborator Author

sffc commented Dec 8, 2019

This is still a really important open question. We are exploring options in the Temporal repository at tc39/proposal-temporal#290 because it would be nice for the Temporal month and Intl.DisplayNames month to match.

Can we recommend that when browsers ship this feature, they hold back on shipping the month and maybe also weekday types for the time being until we have this issue resolved?

@ljharb
Copy link
Member

ljharb commented Dec 8, 2019

If that's going to be a request, that seems like a reason not to request stage 3 until it's resolved.

@sffc
Copy link
Collaborator Author

sffc commented Dec 8, 2019

This proposal is already Stage 3 unfortunately. The issue about leap months came up after we had asked for Stage 3. In any case, I do not want to block the rest of the proposal on this edge case, since the rest of it is really solid and unlikely to be affected by our decision on month names.

@ljharb
Copy link
Member

ljharb commented Dec 8, 2019

Oh, my mistake, I thought this was Temporal :-) in that case that does make sense to either ask implementers to partially ship, or to drop it back to stage 2.

@sffc
Copy link
Collaborator Author

sffc commented Dec 12, 2019

Per today's ECMA-402 meeting, we are removing all date/time types from Intl.DisplayNames and saving them for V2, once Temporal has set the precedent. I expect these to be added in a follow-on proposal or PR later in 2020.

@sffc sffc added the Later For future version to consider, NOT now. label Dec 12, 2019
@sffc
Copy link
Collaborator Author

sffc commented Feb 13, 2020

I'm going to keep the conversation going here, since we do need to resolve this issue for both Temporal and DisplayNames, and I would like it to be resolved in 2020.

Background: Many lunisolar calendars have the concept of "leap months", which are extra months added to a year in order to maintain rough alignment between moon cycles and solar years.

In the Hebrew and Chinese lunisolar calendars, an existing month is "duplicated". For example, in Hebrew, the last month, "Adar", is duplicated into "Adar I" and "Adar II". In the Chinese calendar, the duplicated month could be any of the months, not just the last month; according to Wikipedia:

The first month without a mid-climate is the leap, or intercalary, month. In other words, the first month that doesn't include a major solar term is the leap month.[17] Leap months are numbered with rùn 閏, the character for "intercalary", plus the name of the month they follow. In 2017, the intercalary month after month six was called Rùn Liùyuè, or "intercalary sixth month" (閏六月) and written as 6i or 6+. The next intercalary month (in 2020, after month four) will be called Rùn Sìyuè (閏四月) and written 4i or 4+.

Here are some options on how to identify the month:

  1. Month is an integer, leap months use the same numeric value as their non-leap equivalent, and we add an additional optional argument which takes "isLeapMonth". For Chinese, that argument would be true or false. For Hebrew, we would need three cases, since "Adar", "Adar I", and "Adar II" are all separate names.
    • Problem: The user needs to know to use the optional argument. If they pass their month value from Temporal directly into Intl.DisplayNames, they might miss crucial information.
  2. Month is an integer, and we create special numeric values to represent the leap months. For example, in Chinese, a negative number could be the leap version of the corresponding positive number. In Hebrew, we could make 12 be "Adar", 13 be "Adar I", and 14 be "Adar II".
  3. Month is not an integer but rather is a complex type depending on the calendar system. For example, the Hebrew calendar could have something like [12] for "Adar", [12, false] for "Adar I", and [12, true] for "Adar II". The Chinese calendar could have [4] for "Sìyuè" and [4, true] for "Rùn Sìyuè".
    • Problem: We lose a certain simplicity such as the ability to compare two month values using the < or > operator.
  4. Month is a first-class type, Temporal.Month, with semantics defined by the calendar system.
    • Problem: This would need to be proposed to Temporal. So far all Temporal types have been clean integers, and this would add complexity to the data model.

Thoughts?

@sffc
Copy link
Collaborator Author

sffc commented Feb 14, 2020

Additional ideas from discussion with @FrankYFTang and @echeran:

  1. Intl.DisplayNames.prototype.of for type="month" take a year and returns an array of all the months in that year, sorted in order. The list could be length 12 or length 13.
  2. Do not expose month names in Intl.DisplayNames, instead relying on Intl.DateTimeFormat with month: "long".

Also consider making the Temporal Chinese date return a half number like 4.5 for leap month 4.

@sffc
Copy link
Collaborator Author

sffc commented May 28, 2020

As posted in tc39/proposal-temporal#573:

I am increasingly liking the idea of passing a proper YearMonth into Intl.DisplayNames. A YearMonth unambiguously says what calendar system and which month in which year you want to format. So for example, to get Ayar II, you could do:

const names = new Intl.DisplayNames("en-US", { type: "month" });
const ayarII = names.of(Temporal.YearMonth.from({
  calendar: "hebrew",
  year: 5779,
  month: 7,
});
console.log(ayarII);  // "Ayar II"

@FrankYFTang
Copy link
Collaborator

I put together a v2 repo on https://github.com/FrankYFTang/intl-displaynames-v2/ please move the future discussion there.

@FrankYFTang
Copy link
Collaborator

This proposal reach stage 4 in TC39 2020 Sept meeting. Close this issue in this repo, move all discussion to tc39/proposal-intl-displaynames-v2#11 please

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Later For future version to consider, NOT now.
Projects
None yet
Development

No branches or pull requests

3 participants