diff --git a/components/calendar/src/any_calendar.rs b/components/calendar/src/any_calendar.rs index df32c066948..6ce6ed1164e 100644 --- a/components/calendar/src/any_calendar.rs +++ b/components/calendar/src/any_calendar.rs @@ -1792,13 +1792,13 @@ mod tests { DateError::UnknownMonthCode(MonthCode(tinystr!(4, "M13"))), ); - single_test_roundtrip(indian, Some(("saka", Some(0))), 100, "M03", 1); + single_test_roundtrip(indian, Some(("shaka", Some(0))), 100, "M03", 1); single_test_roundtrip(indian, None, 2000, "M12", 1); single_test_roundtrip(indian, None, -100, "M03", 1); - single_test_roundtrip(indian, Some(("saka", Some(0))), 0, "M03", 1); + single_test_roundtrip(indian, Some(("shaka", Some(0))), 0, "M03", 1); single_test_error( indian, - Some(("saka", Some(0))), + Some(("shaka", Some(0))), 100, "M13", 1, @@ -1937,8 +1937,8 @@ mod tests { DateError::UnknownMonthCode(MonthCode(tinystr!(4, "M9"))), ); - single_test_roundtrip(roc, Some(("minguo", Some(1))), 10, "M05", 3); - single_test_roundtrip(roc, Some(("minguo-qian", Some(0))), 15, "M01", 10); + single_test_roundtrip(roc, Some(("roc", Some(1))), 10, "M05", 3); + single_test_roundtrip(roc, Some(("broc", Some(0))), 15, "M01", 10); single_test_roundtrip(roc, None, 100, "M10", 30); single_test_roundtrip(hijri_simulated, Some(("ah", Some(0))), 477, "M03", 1); diff --git a/components/calendar/src/cal/hijri.rs b/components/calendar/src/cal/hijri.rs index ef3a6341431..4232b4d5293 100644 --- a/components/calendar/src/cal/hijri.rs +++ b/components/calendar/src/cal/hijri.rs @@ -23,7 +23,7 @@ use crate::cal::hijri_ummalqura_data::{UMMALQURA_DATA, UMMALQURA_DATA_STARTING_Y use crate::cal::iso::{Iso, IsoDateInner}; use crate::calendar_arithmetic::PrecomputedDataSource; use crate::calendar_arithmetic::{ArithmeticDate, CalendarArithmetic}; -use crate::error::DateError; +use crate::error::{year_check, DateError}; use crate::provider::hijri::PackedHijriYearInfo; use crate::provider::hijri::{CalendarHijriSimulatedMeccaV1, HijriData}; use crate::types::EraYear; @@ -36,11 +36,20 @@ use icu_provider::prelude::*; use tinystr::tinystr; fn era_year(year: i32) -> EraYear { - types::EraYear { - era: tinystr!(16, "ah"), - era_index: Some(0), - year, - ambiguity: types::YearAmbiguity::CenturyRequired, + if year > 0 { + types::EraYear { + era: tinystr!(16, "ah"), + era_index: Some(0), + year, + ambiguity: types::YearAmbiguity::CenturyRequired, + } + } else { + types::EraYear { + era: tinystr!(16, "bh"), + era_index: Some(1), + year: 1 - year, + ambiguity: types::YearAmbiguity::CenturyRequired, + } } } @@ -48,7 +57,7 @@ fn era_year(year: i32) -> EraYear { /// /// # Era codes /// -/// This calendar uses a single era code `ah`, Anno Hegirae. Dates before this era use negative years. +/// This calendar uses two era codes: `ah`, and `bh`, corresponding to the Anno Hegirae and Before Hijrah eras /// /// # Month codes /// @@ -79,7 +88,7 @@ impl HijriSimulatedLocation { /// /// # Era codes /// -/// This calendar uses a single era code `ah`, Anno Hegirae. Dates before this era use negative years. +/// This calendar uses two era codes: `ah`, and `bh`, corresponding to the Anno Hegirae and Before Hijrah eras /// /// # Month codes /// @@ -97,7 +106,7 @@ pub struct HijriUmmAlQura; /// /// # Era codes /// -/// This calendar uses a single era code `ah`, Anno Hegirae. Dates before this era use negative years. +/// This calendar uses two era codes: `ah`, and `bh`, corresponding to the Anno Hegirae and Before Hijrah eras /// /// # Month codes /// @@ -374,7 +383,8 @@ impl Calendar for HijriSimulated { day: u8, ) -> Result { let year = match era { - Some("islamic-rgsa" | "ah") | None => year, + Some("ah") | None => year_check(year, 1..)?, + Some("bh") => 1 - year_check(year, 1..)?, Some(_) => return Err(DateError::UnknownEra), }; let Some((month, false)) = month_code.parsed() else { @@ -656,7 +666,8 @@ impl Calendar for HijriUmmAlQura { day: u8, ) -> Result { let year = match era { - Some("islamic-umalqura" | "ah") | None => year, + Some("ah") | None => year_check(year, 1..)?, + Some("bh") => 1 - year_check(year, 1..)?, Some(_) => return Err(DateError::UnknownEra), }; let Some((month, false)) = month_code.parsed() else { @@ -881,9 +892,8 @@ impl Calendar for HijriTabular { day: u8, ) -> Result { let year = match era { - Some("ah") | None => year, - Some("islamic-civil" | "islamicc") if self.epoch == HijriTabularEpoch::Friday => year, - Some("islamic-tbla") if self.epoch == HijriTabularEpoch::Thursday => year, + Some("ah") | None => year_check(year, 1..)?, + Some("bh") => 1 - year_check(year, 1..)?, Some(_) => return Err(DateError::UnknownEra), }; @@ -1893,11 +1903,9 @@ mod test { #[test] fn test_regression_4914() { // https://github.com/unicode-org/icu4x/issues/4914 - let cal = HijriUmmAlQura::new(); - let era = "islamic-umalqura"; - let year = -6823; - let month_code = MonthCode(tinystr!(4, "M01")); - let dt = cal.from_codes(Some(era), year, month_code, 1).unwrap(); + let dt = HijriUmmAlQura::new() + .from_codes(Some("bh"), 6824, MonthCode::new_normal(1).unwrap(), 1) + .unwrap(); assert_eq!(dt.0.day, 1); assert_eq!(dt.0.month, 1); assert_eq!(dt.0.year.value, -6823); diff --git a/components/calendar/src/cal/indian.rs b/components/calendar/src/cal/indian.rs index 2e7786ddc39..608e85e2ead 100644 --- a/components/calendar/src/cal/indian.rs +++ b/components/calendar/src/cal/indian.rs @@ -31,7 +31,7 @@ use tinystr::tinystr; /// /// # Era codes /// -/// This calendar uses a single era code: `saka`, with Saka 0 being 78 CE. Dates before this era use negative years. +/// This calendar uses a single era code: `shaka`, with Śaka 0 being 78 CE. Dates before this era use negative years. /// /// # Month codes /// @@ -84,10 +84,10 @@ impl CalendarArithmetic for Indian { } } -/// The Saka calendar starts on the 81st day of the Gregorian year (March 22 or 21) +/// The Śaka era starts on the 81st day of the Gregorian year (March 22 or 21) /// which is an 80 day offset. This number should be subtracted from Gregorian dates const DAY_OFFSET: u16 = 80; -/// The Saka calendar is 78 years behind Gregorian. This number should be added to Gregorian dates +/// The Śaka era is 78 years behind Gregorian. This number should be added to Gregorian dates const YEAR_OFFSET: i32 = 78; impl crate::cal::scaffold::UnstableSealed for Indian {} @@ -102,7 +102,7 @@ impl Calendar for Indian { day: u8, ) -> Result { let year = match era { - Some("saka") | None => year, + Some("shaka") | None => year, Some(_) => return Err(DateError::UnknownEra), }; ArithmeticDate::new_from_codes(self, year, month_code, day).map(IndianDateInner) @@ -120,7 +120,7 @@ impl Calendar for Indian { fn from_iso(&self, iso: IsoDateInner) -> IndianDateInner { // Get day number in year (1 indexed) let day_of_year_iso = Iso::day_of_year(iso); - // Convert to Saka year + // Convert to Śaka year let mut year = iso.0.year - YEAR_OFFSET; // This is in the previous Indian year let day_of_year_indian = if day_of_year_iso <= DAY_OFFSET { @@ -186,7 +186,7 @@ impl Calendar for Indian { fn year_info(&self, date: &Self::DateInner) -> Self::Year { types::EraYear { era_index: Some(0), - era: tinystr!(16, "saka"), + era: tinystr!(16, "shaka"), year: self.extended_year(date), ambiguity: types::YearAmbiguity::CenturyRequired, } @@ -320,19 +320,19 @@ mod tests { fn check_case(case: TestCase) { let iso = Date::try_new_iso(case.iso_year, case.iso_month, case.iso_day).unwrap(); - let saka = iso.to_calendar(Indian); + let indian = iso.to_calendar(Indian); assert_eq!( - saka.era_year().year, + indian.era_year().year, case.expected_year, "Year check failed for case: {case:?}" ); assert_eq!( - saka.month().ordinal, + indian.month().ordinal, case.expected_month, "Month check failed for case: {case:?}" ); assert_eq!( - saka.day_of_month().0, + indian.day_of_month().0, case.expected_day, "Day check failed for case: {case:?}" ); diff --git a/components/calendar/src/cal/roc.rs b/components/calendar/src/cal/roc.rs index 5f106e9dce4..2f1cdf021f9 100644 --- a/components/calendar/src/cal/roc.rs +++ b/components/calendar/src/cal/roc.rs @@ -39,8 +39,8 @@ const ROC_ERA_OFFSET: i32 = 1911; /// /// # Era codes /// -/// This calendar uses two era codes: `minguo`, corresponding to years in the 民國 era (CE year 1912 and -/// after), and `minguo-qian`, corresponding to years before the 民國 era (CE year 1911 and before). +/// This calendar uses two era codes: `roc`, corresponding to years in the 民國 era (CE year 1912 and +/// after), and `broc`, corresponding to years before the 民國 era (CE year 1911 and before). /// /// /// # Month codes @@ -67,8 +67,8 @@ impl Calendar for Roc { day: u8, ) -> Result { let year = match era { - Some("minguo") | None => ROC_ERA_OFFSET + year_check(year, 1..)?, - Some("minguo-qian") => ROC_ERA_OFFSET + 1 - year_check(year, 1..)?, + Some("roc") | None => ROC_ERA_OFFSET + year_check(year, 1..)?, + Some("broc") => ROC_ERA_OFFSET + 1 - year_check(year, 1..)?, Some(_) => return Err(DateError::UnknownEra), }; @@ -129,14 +129,14 @@ impl Calendar for Roc { let extended_year = self.extended_year(date); if extended_year > ROC_ERA_OFFSET { types::EraYear { - era: tinystr!(16, "minguo"), + era: tinystr!(16, "roc"), era_index: Some(1), year: extended_year.saturating_sub(ROC_ERA_OFFSET), ambiguity: types::YearAmbiguity::CenturyRequired, } } else { types::EraYear { - era: tinystr!(16, "minguo-qian"), + era: tinystr!(16, "broc"), era_index: Some(0), year: (ROC_ERA_OFFSET + 1).saturating_sub(extended_year), ambiguity: types::YearAmbiguity::EraAndCenturyRequired, @@ -185,7 +185,7 @@ impl Date { /// let date_roc = Date::try_new_roc(1, 2, 3) /// .expect("Failed to initialize ROC Date instance."); /// - /// assert_eq!(date_roc.era_year().era, tinystr!(16, "minguo")); + /// assert_eq!(date_roc.era_year().era, tinystr!(16, "roc")); /// assert_eq!(date_roc.era_year().year, 1, "ROC year check failed!"); /// assert_eq!(date_roc.month().ordinal, 2, "ROC month check failed!"); /// assert_eq!(date_roc.day_of_month().0, 3, "ROC day of month check failed!"); @@ -264,7 +264,7 @@ mod test { iso_month: 1, iso_day: 1, expected_year: 1, - expected_era: "minguo", + expected_era: "roc", expected_month: 1, expected_day: 1, }, @@ -274,7 +274,7 @@ mod test { iso_month: 2, iso_day: 29, expected_year: 1, - expected_era: "minguo", + expected_era: "roc", expected_month: 2, expected_day: 29, }, @@ -284,7 +284,7 @@ mod test { iso_month: 6, iso_day: 30, expected_year: 2, - expected_era: "minguo", + expected_era: "roc", expected_month: 6, expected_day: 30, }, @@ -294,7 +294,7 @@ mod test { iso_month: 7, iso_day: 13, expected_year: 112, - expected_era: "minguo", + expected_era: "roc", expected_month: 7, expected_day: 13, }, @@ -318,7 +318,7 @@ mod test { iso_month: 12, iso_day: 31, expected_year: 1, - expected_era: "minguo-qian", + expected_era: "broc", expected_month: 12, expected_day: 31, }, @@ -328,7 +328,7 @@ mod test { iso_month: 1, iso_day: 1, expected_year: 1, - expected_era: "minguo-qian", + expected_era: "broc", expected_month: 1, expected_day: 1, }, @@ -338,7 +338,7 @@ mod test { iso_month: 12, iso_day: 31, expected_year: 2, - expected_era: "minguo-qian", + expected_era: "broc", expected_month: 12, expected_day: 31, }, @@ -348,7 +348,7 @@ mod test { iso_month: 2, iso_day: 29, expected_year: 4, - expected_era: "minguo-qian", + expected_era: "broc", expected_month: 2, expected_day: 29, }, @@ -358,7 +358,7 @@ mod test { iso_month: 1, iso_day: 1, expected_year: 1911, - expected_era: "minguo-qian", + expected_era: "broc", expected_month: 1, expected_day: 1, }, @@ -368,7 +368,7 @@ mod test { iso_month: 12, iso_day: 31, expected_year: 1912, - expected_era: "minguo-qian", + expected_era: "broc", expected_month: 12, expected_day: 31, }, diff --git a/provider/source/src/calendar/eras.rs b/provider/source/src/calendar/eras.rs index ffd59abdd93..1273ad81ac5 100644 --- a/provider/source/src/calendar/eras.rs +++ b/provider/source/src/calendar/eras.rs @@ -163,11 +163,11 @@ fn process_era_dates_map( "gregory-inverse" => Some("bce"), "gregory" => Some("ce"), "hebrew" => Some("am"), - "indian" => Some("saka"), + "indian" => Some("shaka"), islamic if islamic.starts_with("islamic") => Some("ah"), "persian" => Some("ap"), - "roc-inverse" => Some("minguo-qian"), - "roc" => Some("minguo"), + "roc-inverse" => Some("broc"), + "roc" => Some("roc"), "chinese" | "dangi" => None, "meiji" | "reiwa" | "taisho" | "showa" | "heisei" => Some(code), c => unreachable!("{c:?}"),