Skip to content
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

CalendarFieldDescriptors: Require eraYear to be alway positive? #2900

Open
anba opened this issue Jun 19, 2024 · 8 comments
Open

CalendarFieldDescriptors: Require eraYear to be alway positive? #2900

anba opened this issue Jun 19, 2024 · 8 comments

Comments

@anba
Copy link
Contributor

anba commented Jun 19, 2024

CalendarFieldDescriptors:

For example, "era" (with ToString conversion) and "eraYear" (with ToIntegerWithTruncation conversion) are returned when calendar is "gregory" or "japanese" and type is date or year-month or a List containing "year".

Should eraYear require ToPositiveIntegerWithTruncation instead of ToIntegerWithTruncation?

The current SpiderMonkey implementations uses ICU4X, which doesn't allow negative era years. The consensus from #1231 (comment) matches my understanding:

  • year is the algorithmic (signed) year, in order to make it easy to write code using the ISO calendar that "just works" with non-ISO calendars.
  • eraYear is the numeric year within the era.

But the implementation notes from #1231 (comment) suddenly state that negative era years are allowed:

  • [...] eraYear can be negative, for example when referring to dates before the first era.

Maybe this different implementation is because the polyfill accepts eraYear as an equivalent to year (#2870)?

I'd prefer to restrict signed years for algorithmic use to the year property and eraYear to count up from the start of the era.


The polyfill allows negative eraYear inputs in some cases. I'm not sure about the exact rules, but I guess the polyfill allows negative eraYear for all eras but the very first era. For example this works in the polyfill:

// -1 CE, which is resolved to 2 BCE.
Temporal.PlainDate.from({calendar: "gregory", era: "ce", eraYear: -1, month: 1, day: 1})

Whereas this throws:

Temporal.PlainDate.from({calendar: "gregory", era: "bce", eraYear: -1, month: 1, day: 1})
@justingrant
Copy link
Collaborator

justingrant commented Jun 19, 2024

The current SpiderMonkey implementations uses ICU4X, which doesn't allow negative era years.

@sffc How does ICU4X handle far-past years in calendars which have positive-counting (not inverse) eras as their first era? Does it refuse to create dates before the first year of those eras? If not, then eraYear should be able to be negative, right?

@anba
Copy link
Contributor Author

anba commented Jun 19, 2024

@justingrant
Copy link
Collaborator

Looking at the docs for the Ethiopian calendar:

This calendar supports three era codes, based on what mode it is in. In the Amete Mihret scheme it has the "incar" and "pre-incar" eras, 1 Incarnation is 9 CE. In the Amete Alem scheme, it instead has a single era, "mundi, where 1 Anno Mundi is 5493 BCE. Dates before that use negative year numbers.

What is the eraYear in the Amete Mihret scheme for 6000 BCE? I'd assume it's -6 or something like that.

Or should it throw because the world hadn't been created yet so time didn't exist? 😄

@anba
Copy link
Contributor Author

anba commented Jun 20, 2024

The ISO date "-006000-01-01" is resolved to the era year 6009 in the "pre-incar" era.

Output:

AmeteMihret: 6009-6-22 "pre-incar"
AmeteAlem: -508-6-22 "mundi"
use icu::calendar::{Calendar, Date};
use icu::calendar::ethiopian::{Ethiopian, EthiopianEraStyle};

fn main() {
  let iso = Date::try_new_iso_date(-6000, 1, 1).unwrap();

  let styles = [
    EthiopianEraStyle::AmeteMihret,
    EthiopianEraStyle::AmeteAlem,
  ];

  for style in styles {
    let cal = Ethiopian::new_with_era_style(style);
    let date = cal.date_from_iso(iso);
    let era = cal.year(&date).era.0;

    println!(
      "{}: {}-{}-{} {}",
      format!("{style:?}"),
      cal.year(&date).number,
      cal.month(&date).ordinal,
      cal.day_of_month(&date).0,
      format!("{era:?}"),
    );
  }
}

@sffc
Copy link
Collaborator

sffc commented Jun 20, 2024

eraYear can be negative in ICU4X. unicode-org/icu4x#5087

Such years are usually nonsense. But, we've been working for a long time that all ISO dates are representable in all calendars, and calendars just need to do something reasonable (the definition of "reasonable" is a topic for another thread, #2869).

@anba
Copy link
Contributor Author

anba commented Jun 20, 2024

eraYear can be negative in ICU4X. unicode-org/icu4x#5087

This only applies to calendars with a single era, right?

CalendarDateEraYear requires to return undefined for calendars which don't use eras. I'm interpreting this to mean that calendar systems which have a single era (in ICU4X) don't actually use eras. So for example eraYear for the Hebrew calendar should always return undefined in Temporal.

@sffc
Copy link
Collaborator

sffc commented Jun 20, 2024

For some additional discussion on Ethiopian, please see tc39/proposal-intl-era-monthcode#4. I think we probably want to support negative eraYear with mixed eras, definitely on input and probably on output, though I could be convinced otherwise if we can work out Ethiopian. What is the advantage to adding this restriction, though?

@anba
Copy link
Contributor Author

anba commented Jun 20, 2024

I think we probably want to support negative eraYear with mixed eras, [...]

Can you explain "mixed eras"? I'm not sure what you mean and I don't want to misinterpret your comment.

What is the advantage to adding this restriction, though?

Adding this restriction avoids having to define how to interpret inputs like "-100 BCE" or "-123 Reiwa".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants