-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Simple generalizable algorithm for CalendarDateDifference #16
Comments
I like this algorithm and it is close to what I would have implemented if this had not been further specified. Point 2 is interesting but makes sense. Will there be a similar algorithm for adding date differences to dates that preserves roundtrip? |
Does this mean to compare month code lexicographically as well? This could potentially be tricky: in the chinese calendar, M05L occurs after M05, but in the Hebrew calendar, M05L (Adar I) occurs before M05 (Adar II). Also tricky for Hindu calendars (see #18). (ICU4X retains a distinction here for formatting months specifically: it uses M06L for Adar II when formatting only to pick up the alternate month name, but Adar II's month identity is still M05, which matches Temporal) I do not think we will ever have calendars where the month codes do not have a total ordering, I think it would be sufficient to ask each calendar to define a total ordering of month codes (could be done with two lines of prose for the existing calendars).
What is actually done here? I assume this is just "remove the L if needed". But it could also be "go down a month" which can amount to removing the L and subtracting 1 in the case of Hebrew. Or going one month up/down based on how close to the end of the month it is. "constrain" says "nearest valid value" but that's harder to reason about here. |
In current Temporal, Adar II (and regular, non-leap Adar) is M06, not M05L. This is because regardless of the calendar, Temporal currently defines the leap month's month code as the code of the previous month (in this case M05 which is Shevet) with an L appended. There is no expectation that you can remove the L and end up with the normal-month equivalent to the leap month. Especially given that in some calendars there may be two months that could be considered the "normal-month equivalent" if months are merged. Temporal.PlainDate.from({year: 5785, monthCode: 'M05', day: 1, calendar: "hebrew"}).toLocaleString("en", {calendar: 'hebrew'})
// => '1 Shevat 5785'
Temporal.PlainDate.from({year: 5785, monthCode: 'M05L', day: 1, calendar: "hebrew"}).toLocaleString("en", {calendar: 'hebrew'})
// => '1 Adar 5785'
Temporal.PlainDate.from({year: 5785, monthCode: 'M06', day: 1, calendar: "hebrew"}).toLocaleString("en", {calendar: 'hebrew'})
// => '1 Adar 5785' Note that the month code should have no impact on rounding or constraining. If you have a date with M05L and you add one year, you get M06. Temporal.PlainDate.from({year: 5785, monthCode: 'M05L', day: 1, calendar: "hebrew"}).add({years: 1}).monthCode
// => 'M06' This behavior ensures that months can be compared and sorted lexicographically. It also sidesteps the problem of which month should be considered the "normal" month corresponding to each leap month, because my understanding is that some calendars may have 2 months that merge into one. If we want to change this numbering scheme, we should probably figure this out ASAP before Temporal goes to stage 4. Thanks! |
Ah, my bad. This is also what ICU4X does, I miscounted. In that case this is probably fine |
What do we mean when we say "Constrain d0 to a real year/month" when counting backwards (d1 < d0)? For example:
By the current algorithm, we are happy to have a "-1 Year" in the duration, but after constraining, we get a day in M08 which is below the target date. |
I guess another question here is, what should the result of the following operation be? // `x` is a year containing a month M08L
Temporal.PlainDate.from({ calendar: "chinese", year: x, month: "M08L", day: 20 })
.subtract({ years: 1, months: 1 }) Should the month end up being And what should the answer be if the |
Do you mean if
The spec text is purposefully vague about this, deferring to the calendar:
|
In the last Temporal meeting we discussed a possible algorithm for CalendarDateDifference that is generalizable to lunisolar calendars. @sffc suggested that ICU4X might implement this. I don't know whether it's in scope for this proposal to specify it, but I'm copying it here as an FYI. This is written in loose prose, not a formal description.
To take the difference between start date d0 and target date d1:
We are adopting a similar algorithm for DifferenceISODate in Temporal. The more formal description is here: https://github.com/tc39/proposal-temporal/pull/2759/files#diff-113bc23f7ddc769c78deac4268f2400a0a8ca75258f4a6a8af8219cf430a0788R828-R863
(with the caveat that step 2 is a no-op for ISO 8601 calendar and so not present, and we compare month numbers instead of month codes lexicographically because they are the same for the ISO 8601 calendar.)
The text was updated successfully, but these errors were encountered: