Skip to content

Commit 29996df

Browse files
Calendar cleanups and bug fix (#6380)
Fixes #5069
1 parent 67d49ce commit 29996df

File tree

22 files changed

+662
-784
lines changed

22 files changed

+662
-784
lines changed

components/calendar/src/cal/buddhist.rs

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,16 @@ impl Calendar for Buddhist {
106106

107107
/// The calendar-specific year represented by `date`
108108
fn year(&self, date: &Self::DateInner) -> types::YearInfo {
109-
iso_year_as_buddhist(date.0.year)
109+
let buddhist_year = date.0.year + BUDDHIST_ERA_OFFSET;
110+
types::YearInfo::new(
111+
buddhist_year,
112+
types::EraYear {
113+
standard_era: tinystr!(16, "buddhist").into(),
114+
formatting_era: types::FormattingEra::Index(0, tinystr!(16, "BE")),
115+
era_year: buddhist_year,
116+
ambiguity: types::YearAmbiguity::CenturyRequired,
117+
},
118+
)
110119
}
111120

112121
fn is_in_leap_year(&self, date: &Self::DateInner) -> bool {
@@ -158,19 +167,6 @@ impl Date<Buddhist> {
158167
}
159168
}
160169

161-
fn iso_year_as_buddhist(year: i32) -> types::YearInfo {
162-
let buddhist_year = year + BUDDHIST_ERA_OFFSET;
163-
types::YearInfo::new(
164-
buddhist_year,
165-
types::EraYear {
166-
standard_era: tinystr!(16, "buddhist").into(),
167-
formatting_era: types::FormattingEra::Index(0, tinystr!(16, "BE")),
168-
era_year: buddhist_year,
169-
ambiguity: types::YearAmbiguity::CenturyRequired,
170-
},
171-
)
172-
}
173-
174170
#[cfg(test)]
175171
mod test {
176172
use calendrical_calculations::rata_die::RataDie;

components/calendar/src/cal/chinese.rs

Lines changed: 28 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
2020
use crate::cal::chinese_based::{
2121
chinese_based_ordinal_lunar_month_from_code, ChineseBasedDateInner,
22-
ChineseBasedPrecomputedData, ChineseBasedWithDataLoading, ChineseBasedYearInfo,
22+
ChineseBasedPrecomputedData, ChineseBasedWithDataLoading,
2323
};
2424
use crate::cal::iso::Iso;
2525
use crate::calendar_arithmetic::CalendarArithmetic;
@@ -173,9 +173,9 @@ impl Calendar for Chinese {
173173
month_code: types::MonthCode,
174174
day: u8,
175175
) -> Result<Self::DateInner, DateError> {
176-
let year_info = self.get_precomputed_data().load_or_compute_info(year);
176+
let year = self.get_precomputed_data().load_or_compute_info(year);
177177

178-
let Some(month) = chinese_based_ordinal_lunar_month_from_code(month_code, year_info) else {
178+
let Some(month) = chinese_based_ordinal_lunar_month_from_code(month_code, year) else {
179179
return Err(DateError::UnknownMonthCode(month_code));
180180
};
181181

@@ -184,7 +184,7 @@ impl Calendar for Chinese {
184184
_ => return Err(DateError::UnknownEra),
185185
}
186186

187-
Inner::new_from_ordinals(year, month, day, year_info)
187+
Inner::new_from_ordinals(year, month, day)
188188
.map(ChineseBasedDateInner)
189189
.map(ChineseDateInner)
190190
}
@@ -243,11 +243,17 @@ impl Calendar for Chinese {
243243
}
244244

245245
fn year(&self, date: &Self::DateInner) -> types::YearInfo {
246-
Self::format_chinese_year(date.0 .0.year, Some(date.0 .0.year_info))
246+
let year = date.0 .0.year;
247+
let cyclic = (year.value - 1).rem_euclid(60) as u8;
248+
let cyclic = NonZeroU8::new(cyclic + 1).unwrap_or(NonZeroU8::MIN); // 1-indexed
249+
let rata_die_in_year = date.0 .0.year.new_year::<ChineseCB>();
250+
let iso_year = Iso::from_fixed(rata_die_in_year).year();
251+
let related_iso = iso_year.era_year_or_extended();
252+
types::YearInfo::new_cyclic(year.value, cyclic, related_iso)
247253
}
248254

249255
fn is_in_leap_year(&self, date: &Self::DateInner) -> bool {
250-
Self::is_leap_year(date.0 .0.year, date.0 .0.year_info)
256+
Self::provided_year_is_leap(date.0 .0.year)
251257
}
252258

253259
/// The calendar-specific month code represented by `date`;
@@ -307,11 +313,11 @@ impl<A: AsCalendar<Calendar = Chinese>> Date<A> {
307313
day: u8,
308314
calendar: A,
309315
) -> Result<Date<A>, DateError> {
310-
let year_info = calendar
316+
let year = calendar
311317
.as_calendar()
312318
.get_precomputed_data()
313319
.load_or_compute_info(year);
314-
let arithmetic = Inner::new_from_ordinals(year, month, day, year_info);
320+
let arithmetic = Inner::new_from_ordinals(year, month, day);
315321
Ok(Date::from_raw(
316322
ChineseDateInner(ChineseBasedDateInner(arithmetic?)),
317323
calendar,
@@ -327,26 +333,6 @@ impl ChineseBasedWithDataLoading for Chinese {
327333
}
328334
}
329335

330-
impl Chinese {
331-
/// Get a YearInfo from an integer Chinese year; optionally, a `ChineseBasedYearInfo`
332-
/// can be passed in for faster results.
333-
fn format_chinese_year(
334-
year: i32,
335-
year_info_option: Option<ChineseBasedYearInfo>,
336-
) -> types::YearInfo {
337-
let cyclic = (year - 1).rem_euclid(60) as u8;
338-
let cyclic = NonZeroU8::new(cyclic + 1).unwrap_or(NonZeroU8::MIN); // 1-indexed
339-
let rata_die_in_year = if let Some(info) = year_info_option {
340-
info.new_year::<ChineseCB>(year)
341-
} else {
342-
Inner::fixed_mid_year_from_year(year)
343-
};
344-
let iso_year = Iso::from_fixed(rata_die_in_year).year();
345-
let related_iso = iso_year.era_year_or_extended();
346-
types::YearInfo::new_cyclic(year, cyclic, related_iso)
347-
}
348-
}
349-
350336
#[cfg(test)]
351337
mod test {
352338
use super::*;
@@ -474,7 +460,7 @@ mod test {
474460
let chinese =
475461
Inner::chinese_based_date_from_fixed(chinese.0, rata_die, iso.inner.0);
476462
assert_eq!(
477-
case.expected_year, chinese.0.year,
463+
case.expected_year, chinese.0.year.value,
478464
"[{calendar_type}] Chinese from fixed failed, case: {case:?}"
479465
);
480466
assert_eq!(
@@ -687,7 +673,7 @@ mod test {
687673
#[test]
688674
fn test_month_days() {
689675
let year = 4660;
690-
let year_info =
676+
let year =
691677
ChineseBasedPrecomputedData::<<Chinese as ChineseBasedWithDataLoading>::CB>::default()
692678
.load_or_compute_info(year);
693679
let cases = [
@@ -706,7 +692,7 @@ mod test {
706692
(13, 30),
707693
];
708694
for case in cases {
709-
let days_in_month = Chinese::month_days(year, case.0, year_info);
695+
let days_in_month = Chinese::days_in_provided_month(year, case.0);
710696
assert_eq!(
711697
case.1, days_in_month,
712698
"month_days test failed for case: {case:?}"
@@ -840,11 +826,10 @@ mod test {
840826

841827
#[test]
842828
fn test_month_code_to_ordinal() {
843-
let year = 4660;
844829
// construct using ::default() to force recomputation
845-
let year_info =
830+
let year =
846831
ChineseBasedPrecomputedData::<<Chinese as ChineseBasedWithDataLoading>::CB>::default()
847-
.load_or_compute_info(year);
832+
.load_or_compute_info(4660);
848833
let codes = [
849834
(1, tinystr!(4, "M01")),
850835
(2, tinystr!(4, "M02")),
@@ -862,11 +847,12 @@ mod test {
862847
];
863848
for ordinal_code_pair in codes {
864849
let code = MonthCode(ordinal_code_pair.1);
865-
let ordinal = chinese_based_ordinal_lunar_month_from_code(code, year_info);
850+
let ordinal = chinese_based_ordinal_lunar_month_from_code(code, year);
866851
assert_eq!(
867852
ordinal,
868853
Some(ordinal_code_pair.0),
869-
"Code to ordinal failed for year: {year}, code: {code}"
854+
"Code to ordinal failed for year: {}, code: {code}",
855+
year.value
870856
);
871857
}
872858
}
@@ -885,18 +871,18 @@ mod test {
885871
(non_leap_year, tinystr!(4, "M13")),
886872
(leap_year, tinystr!(4, "M13")),
887873
];
888-
for year_code_pair in invalid_codes {
889-
let year = year_code_pair.0;
874+
for (year, code) in invalid_codes {
890875
// construct using ::default() to force recomputation
891-
let year_info = ChineseBasedPrecomputedData::<
876+
let year = ChineseBasedPrecomputedData::<
892877
<Chinese as ChineseBasedWithDataLoading>::CB,
893878
>::default()
894879
.load_or_compute_info(year);
895-
let code = MonthCode(year_code_pair.1);
896-
let ordinal = chinese_based_ordinal_lunar_month_from_code(code, year_info);
880+
let code = MonthCode(code);
881+
let ordinal = chinese_based_ordinal_lunar_month_from_code(code, year);
897882
assert_eq!(
898883
ordinal, None,
899-
"Invalid month code failed for year: {year}, code: {code}"
884+
"Invalid month code failed for year: {}, code: {code}",
885+
year.value
900886
);
901887
}
902888
}

0 commit comments

Comments
 (0)