tc39 / proposal-intl-era-monthcode

To specify necessary details about era, eraYear and monthCode usage with Temporal in internationalization setting (for calendars other than "iso8601").
https://tc39.github.io/proposal-intl-era-monthcode
MIT License
3 stars 3 forks source link

Handling Hindu lunisidereal calendars #18

Open Manishearth opened 1 year ago

Manishearth commented 1 year ago

Nepal uses the Vikram Samvat calendar as an official calendar; this is a problem we will have to deal with eventually.

Hindu lunisidereal calendars are a bit strange, in ways that may affect the model put forth in Temporal, as well as the data model used in CLDR.

Similar to the Chinese calendar, they allow for leap months at any time of the year. We already have a solid solution for this, with month codes like M01L, M02L, etc.

There are three principal ways in which they are strange

Month naming and deleted/merged months

Sometimes months with a leap year will also have a deleted month

In the true version of the Indian lunisolar calendar, months, called kshaya, may also be expunged, when two zodiacal sign transitions occur in one lunar month. Thus, even a 12-month year can have a leap month (as was the case in 1963–4), and a leap year can even have two (as in 1982–3). (source)

This in and of itself isn't a huge deal for our model. The tricky thing is that technically the month with the double transition gets named after both months, e.g. in 1983 there was a month called "Pausha-Magha kshaya", i.e. "Pausha merged with 'lost' Magha". We may wish to produce alternate month codes for these. (perhaps something like M10M)

These months are rare so we can treat them as a special case or just by the name of the first month if we wish.

Some traditions also use a special day name for the "regular" month (this is the Adar II/Adar II/Adar problem again).

Day naming and merged days

The Hindu calendar has 29-30 day lunar months, however they are each split into a waxing and a waning phase. Each day of the month has a name that is derived from the number. (1 to 14) You'll have names like "Shravan Waxing First", "Shravan Waning Fourteenth", "Shravan New Moon" and "Shravan Full Moon". Note that "First" is the second day of the fortnight/month since it will be preceded by a new or full moon.

Day 14 doesn't always occur as a distinct day; for shorter (29-day) months one of the fortnights will have merged day 14 with day 13. I don't yet know what that day is called; I think people call it by both names though not necessarily at once. On calendars it seems to be marked as "day 13/14", and I'm not sure how that is spelled out.

CLDR does already have support for day names. However this is more complicated logic than usual, since the day names aren't a straight up index into the ordinal day in the month. Days 1 through 13 (of the month) will cleanly map to "Waxing New Moon" to "Waxing Day Twelve", but after that it really depends on the precise month since the waxing fortnight may or may not have a distinct Day Thirteen/Fourteen.

One way of solving this problem is treating each fortnight as a unique "month", giving us 24 months in a year (plus two more when there is a leap month). This does solve the problem rather neatly, though we'd still need to figure out day naming for merged Thirteenth/Fourteenth.

This does somewhat match how the days get named, too, it's not as much "Waxing Day Five" as it is "Day Five of the Waxing Phase of Shravan".

Purnimanta vs amanta and split months

Broadly speaking, there are two traditions for month reckoning. Amanta traditions count months from new moon to new moon (like Chinese/Hebrew/Islamic), and Purnimanta traditions count months from full moon to full moon ("purna" is cognate with "full"). We would not treat these two traditions as the same calendar; so we don't have to deal with that, but there's an interesting bit of weirdness that comes out of their need to be consistent.

See, despite being seemingly incompatible traditions, they do end up being used for interchange. This works because the way they are set up, both calendars agree on the month name for the waxing phase of each cycle, but the waning phases differ. E.g. here, the waxing Chaitra is shared between two calendars, but the waning Chaitra occurs either before it or after it, depending.

image

Most festival dates are on the waxing phase, so most dates interchange directly, and for festivals in the waning phase (e.g. Janmashtami they get two dates listed (e.g. "Amanta: Shravan Krishna Ashtami, Purnimanta: Bhadrapad Krishna Ashtami"[^1]).

So far, still fine, as long as we maintain these calendars as separate calendars.

The real trickiness comes in with the leap months. Leap months are shadow versions of the regular month; roughly speaking none of the festivals occur then, but if the entire month has a significance the leap month does too, and monthly/fortnightly observances (e.g. stuff you do on the eleventh of each fortnight) still happen.

For this to work out in a synchronous form, the Purnimanta and Amanta traditions need to agree on where the leap month is. So if the following is a snippet of a regular year:

x Wax Wane Wax Wane Wax Wane Wax Wane
Amanta Jyeshta Jyeshta Ashad Ashad Shravan Shravan Bhadrapad Bhadrapad
Purnimanta Jyeshta Ashad Ashad Shravan Shravan Bhadrapad Bhadrapad Ashvin

Then this is the format of a leap year with leap Shravan (like 2023):

x Wax Wane Wax Wane Wax Wane Wax Wane Wax Wane
Amanta Jyeshta Jyeshta Ashad Ashad Extra Shravan Extra Shravan Shravan Shravan Bhadrapad Bhadrapad
Purnimanta Jyeshta Ashad Ashad Shravan Extra Shravan Extra Shravan Shravan Bhadrapad Bhadrapad Ashvin

In the Purnimanta calendar, the leap month gets inserted inside the regular month! This is the only way to maintain the correspondence between the two calendars: the leap months match up, and the waxing phases of the regular months match up, and the waning phases of the regular months are "one off".

This is another piece of evidence that the Hindu calendars probably should be modeled as ones with 24 months, since I can't even begin to figure out how date arithmetic would work with split months.


Modeling the Hindu calendars as ones with 24 months, however, bring up a new question: what should Temporal month APIs do? Ultimately, even though the fortnights behave more like months than the real months; people do associate the full 29/30-day months with the term "month" (and its translations). If you told someone that the month is "Shravan Waxing" that would not make sense to them (that is the fortnight, not the month).

Anyway, a lot to think about here, and perhaps worth splitting into sub-issues. I figured I ought to brain-dump the research I'd done so at least there's something to refer to for the future.

cc @FrankYFTang @sffc @ben-allen

[^1]: The "Krishna" in the festival name is only semi-related to the "Krishna" in the day name; "Krishna" means "dark" and is used to talk about the waning phase, this festival just happens to be for someone named after darkness.

sffc commented 1 year ago

If we use the 24-month numbering: we need to figure out date arithmetic. We do not have many invariants when it comes to what calendars do with date arithmetic. It's already the case that CLDR calendars can change the day number when adding/subtracting months (e.g. August 31 + 1 month) and the month number when adding/subtracting years (e.g. 1 Adar II + 1 year). I don't immediately see anything wrong with these hindu calendars changing the ordinal month by 2 when the duration says to add 1 month.

If we use 12-month numbering: nothing really wrong here in the data model; it's just a big headache when formatting. We would need to pull more special casing into the formatting module when we would really prefer as much as possible to keep calendar-specific logic in the calendar module.

Might I suggest the following month code scheme for the 24-month system:

For leap and merge months:

The table becomes:

x Wax Wane Wax Wane Wax Wane Wax Wane Wax Wane
Amanta M03X (Jyeshta) M03Y M04X (Ashad) M04Y M05P (Extra Shravan) M05Q M05X (Shravan) M05Y M06X (Bhadrapad) M06Y
Purnimanta M03X M04Y M04X M05Y M05P M05Q M05X M06Y M06X M07Y
sffc commented 1 year ago

This issue might be better in scope for the month and era code proposal repo: https://github.com/tc39/proposal-intl-era-monthcode

Manishearth commented 1 year ago

Hmm, I think the month codes are rather secondary, first we need to figure out what our model is for months vs fortnights, giving them codes can be done any number of ways afterwards.

But yeah, the scheme you propose seems good. I think the choice of having the month numbers still go to twelve but having two codes per month neatly bridges the gap.

If we use the 24-month numbering: we need to figure out date arithmetic. We do not have many invariants when it comes to what calendars do with date arithmetic. It's already the case that CLDR calendars can change the day number when adding/subtracting months (e.g. August 31 + 1 month) and the month number when adding/subtracting years (e.g. 1 Adar II + 1 year). I don't immediately see anything wrong with these hindu calendars changing the ordinal month by 2 when the duration says to add 1 month.

Yeah I think this is the sticking point: we need to basically decide how different things get special cased.

The tricky bit is that ultimately whilst everything is dated in fortnights, the concept of a "month" is still a month.

I think "add by two" is a reasonable solution. It pins down roughly the behavior people might logically want. The main downside is that it doesn't give any ability to offset by fortnight. Occurs to me that we could add a new "fortnights" entry to the duration types, which isn't accepted by non-fortnight-based calendars but this proposal isn't predicated by that.

There are probably other things to be figured out in arithmetic, though.

sffc commented 1 year ago

There are only two things we need to decide really:

  1. Month code model
  2. Arithmetic date data model

(1) is solvable. As far as (2), the only stated requirement is that the y/m/d tuple be monotonically increasing. It's already not the case that incrementing y by 1 gives you the same date next year or that incrementing m by 1 gives you the same date next month. I'm not sure if there was any interest in extending the invariant to state that incrementing y or m and then normalizing to fit within bounds should be equivalent to date arithmetic.

FrankYFTang commented 1 year ago

Could you please cite your sources for literature review Thanks.

Manishearth commented 1 year ago

Largely Calendrical Calculations, though almost all of this is also covered on the Wikipedia page too (which is quite extensive) https://en.wikipedia.org/wiki/Hindu_calendar

In Calendrical Calculations note that half of the description is in the chapter for old Hindu Calendars, with the chapter for modern hindu calendars referencing it.

Here's the description of leap months

image

They don't really use day names (they have their own day numbering scheme) but they talk about this a bit here. It also covers the case of the case where the lunar day covers two solar days (the second solar day is called "extra ")

image

FrankYFTang commented 1 year ago

so

Reingold, Edward M., and Nachum Dershowitz. Calendrical Calculations: The Ultimate Edition. Cambridge University Press, 2018.

Manishearth commented 1 year ago

Yes,

ptomato commented 8 months ago

Is it OK to move this issue to https://github.com/tc39/proposal-intl-era-monthcode? I don't see anything actionable for Temporal at the moment.

Manishearth commented 8 months ago

Sure

ptomato commented 8 months ago

Someone else may need to do it. I don't seem to have the required permissions.

sffc commented 8 months ago

I don't have permission to move the issue, either. @FrankYFTang @robpalme?

robpalme commented 8 months ago

Try now @sffc

anba commented 1 month ago

New Year is possibly another complication w.r.t. month codes. There are web pages which claim that New Year can happen on "nija Chaitra", "adhika Chaitra", "Chaitra-Vaisakha kshaya", or "Phalguna-Chaitra kshaya". Resulting in the following four special cases (using the Amanta system with 12-month numbering for simplicity):

Month Possible Month Code New Year
Phalguna M12 :x:
adhika Chaitra M12L :x:
nija Chaitra M01 :heavy_check_mark:
Month Possible Month Code New Year
adhika Chaitra M00L :heavy_check_mark:
Chaitra-Vaisakha kshaya M01 :x:
Jyeshtha M03 :x:
Month Possible Month Code New Year
Phalguna M12 :x:
Chaitra-Vaisakha kshaya M01 :heavy_check_mark:
Jyeshtha M02 :x:
Month Possible Month Code New Year
Magha M11 :x:
Phalguna-Chaitra kshaya M00L :heavy_check_mark:
Vaisakha M03 :x:

This results in using different month codes for the same month ("adhika Chaitra" can be "M12L" or "M00L") or using the same month code for different months ("M00L" for both "adhika Chaitra" and "Phalguna-Chaitra kshaya"). Is that going to be a problem?

It'd be good if this can be verified using a more authoritative source than just some random web pages, though.