Skip to content

Commit 1a085e8

Browse files
Change cyclic calendar constructors to use ISO years (#6431)
Also changed `era_year_or_extended` to `era_year_or_related_iso` so it can be used for round-tripping.
1 parent fe2504a commit 1a085e8

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+204
-248
lines changed

components/calendar/README.md

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

components/calendar/benches/convert.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ fn bench_calendar<C: Clone + Calendar>(
1818
group.bench_function(name, |b| {
1919
b.iter(|| {
2020
let converted = black_box(iso).to_calendar(Ref(&calendar));
21-
let year = black_box(converted.year().era_year_or_extended());
21+
let year = black_box(converted.year().era_year_or_related_iso());
2222
let month = black_box(converted.month().ordinal);
2323
let day = black_box(converted.day_of_month().0);
2424
black_box((converted, year, month, day))

components/calendar/benches/date.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ fn bench_date<A: AsCalendar>(date: &mut Date<A>) {
2121
));
2222

2323
// Retrieving vals
24-
let _ = black_box(date.year().era_year_or_extended());
24+
let _ = black_box(date.year().era_year_or_related_iso());
2525
let _ = black_box(date.month().ordinal);
2626
let _ = black_box(date.day_of_month().0);
2727

components/calendar/examples/iso_date_manipulations.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ fn main() {
3232
let date = Date::try_new_iso(year, month, day).expect("date should parse");
3333
println!(
3434
"Year: {}, Month: {}, Day: {}",
35-
date.year().era_year_or_extended(),
35+
date.year().era_year_or_related_iso(),
3636
date.month().ordinal,
3737
date.day_of_month().0,
3838
);

components/calendar/src/any_calendar.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1561,7 +1561,7 @@ mod tests {
15611561

15621562
let roundtrip_year = date.year();
15631563
// FIXME: these APIs should be improved
1564-
let roundtrip_year = roundtrip_year.era_year_or_extended();
1564+
let roundtrip_year = roundtrip_year.era_year_or_related_iso();
15651565
let roundtrip_month = date.month().standard_code;
15661566
let roundtrip_day = date.day_of_month().0;
15671567

components/calendar/src/cal/buddhist.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
//! .expect("Failed to initialize ISO Date instance.");
1212
//! let date_buddhist = Date::new_from_iso(date_iso, Buddhist);
1313
//!
14-
//! assert_eq!(date_buddhist.year().era_year_or_extended(), 2513);
14+
//! assert_eq!(date_buddhist.year().era_year_or_related_iso(), 2513);
1515
//! assert_eq!(date_buddhist.month().ordinal, 1);
1616
//! assert_eq!(date_buddhist.day_of_month().0, 2);
1717
//! ```
@@ -167,7 +167,7 @@ impl Date<Buddhist> {
167167
/// let date_buddhist = Date::try_new_buddhist(1970, 1, 2)
168168
/// .expect("Failed to initialize Buddhist Date instance.");
169169
///
170-
/// assert_eq!(date_buddhist.year().era_year_or_extended(), 1970);
170+
/// assert_eq!(date_buddhist.year().era_year_or_related_iso(), 1970);
171171
/// assert_eq!(date_buddhist.month().ordinal, 1);
172172
/// assert_eq!(date_buddhist.day_of_month().0, 2);
173173
/// ```
@@ -280,7 +280,7 @@ mod test {
280280
let iso1 = Date::try_new_iso(iso_year, iso_month, iso_day).unwrap();
281281
let buddhist1 = iso1.to_calendar(Buddhist);
282282
assert_eq!(
283-
buddhist1.year().era_year_or_extended(),
283+
buddhist1.year().era_year_or_related_iso(),
284284
buddhist_year,
285285
"Iso -> Buddhist year check failed for case: {case:?}"
286286
);
@@ -299,7 +299,7 @@ mod test {
299299
Date::try_new_buddhist(buddhist_year, buddhist_month, buddhist_day).unwrap();
300300
let iso2 = buddhist2.to_calendar(Iso);
301301
assert_eq!(
302-
iso2.year().era_year_or_extended(),
302+
iso2.year().era_year_or_related_iso(),
303303
iso_year,
304304
"Buddhist -> Iso year check failed for case: {case:?}"
305305
);

components/calendar/src/cal/chinese.rs

Lines changed: 32 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@
88
//! use icu::calendar::{cal::Chinese, Date};
99
//!
1010
//! let chinese = Chinese::new();
11-
//! let chinese_date = Date::try_new_chinese_with_calendar(4660, 6, 6, chinese)
11+
//! let chinese_date = Date::try_new_chinese_with_calendar(2023, 6, 6, chinese)
1212
//! .expect("Failed to initialize Chinese Date instance.");
1313
//!
14-
//! assert_eq!(chinese_date.year().era_year_or_extended(), 4660);
14+
//! assert_eq!(chinese_date.year().era_year_or_related_iso(), 2023);
1515
//! assert_eq!(chinese_date.year().cyclic().unwrap().get(), 40);
1616
//! assert_eq!(chinese_date.month().ordinal, 6);
1717
//! assert_eq!(chinese_date.day_of_month().0, 6);
@@ -28,6 +28,7 @@ use crate::error::DateError;
2828
use crate::provider::chinese_based::CalendarChineseV1;
2929
use crate::AsCalendar;
3030
use crate::{types, Calendar, Date, DateDuration, DateDurationUnit};
31+
use calendrical_calculations::chinese_based::{self, ChineseBased};
3132
use calendrical_calculations::rata_die::RataDie;
3233
use core::cmp::Ordering;
3334
use core::num::NonZeroU8;
@@ -211,7 +212,7 @@ impl Calendar for Chinese {
211212
Iso.from_rata_die(self.to_rata_die(date))
212213
}
213214

214-
//Count the number of months in a given year, specified by providing a date
215+
// Count the number of months in a given year, specified by providing a date
215216
// from that year
216217
fn days_in_year(&self, date: &Self::DateInner) -> u16 {
217218
date.0.days_in_year_inner()
@@ -250,11 +251,13 @@ impl Calendar for Chinese {
250251

251252
fn year(&self, date: &Self::DateInner) -> types::YearInfo {
252253
let year = date.0 .0.year;
253-
let cyclic = (year.value - 1).rem_euclid(60) as u8;
254+
let cyclic = (year.related_iso - 4).rem_euclid(60) as u8;
254255
let cyclic = NonZeroU8::new(cyclic + 1).unwrap_or(NonZeroU8::MIN); // 1-indexed
255-
let rata_die_in_year = date.0 .0.year.new_year::<ChineseCB>();
256-
let related_iso = Iso.from_rata_die(rata_die_in_year).0.year;
257-
types::YearInfo::new_cyclic(year.value, cyclic, related_iso)
256+
types::YearInfo::new_cyclic(
257+
chinese_based::Chinese::extended_from_iso(year.related_iso),
258+
cyclic,
259+
year.related_iso,
260+
)
258261
}
259262

260263
fn is_in_leap_year(&self, date: &Self::DateInner) -> bool {
@@ -290,7 +293,7 @@ impl Calendar for Chinese {
290293

291294
impl<A: AsCalendar<Calendar = Chinese>> Date<A> {
292295
/// Construct a new Chinese date from a `year`, `month`, and `day`.
293-
/// `year` represents the Chinese year counted infinitely with -2636 (2637 BCE) as Chinese year 1;
296+
/// `year` represents the [ISO](crate::Iso) year that roughly matches the Chinese year;
294297
/// `month` represents the month of the year ordinally (ex. if it is a leap year, the last month will be 13, not 12);
295298
/// `day` indicates the day of month
296299
///
@@ -303,25 +306,25 @@ impl<A: AsCalendar<Calendar = Chinese>> Date<A> {
303306
/// let chinese = Chinese::new_always_calculating();
304307
///
305308
/// let date_chinese =
306-
/// Date::try_new_chinese_with_calendar(4660, 6, 11, chinese)
309+
/// Date::try_new_chinese_with_calendar(2023, 6, 11, chinese)
307310
/// .expect("Failed to initialize Chinese Date instance.");
308311
///
309-
/// assert_eq!(date_chinese.year().era_year_or_extended(), 4660);
312+
/// assert_eq!(date_chinese.year().era_year_or_related_iso(), 2023);
310313
/// assert_eq!(date_chinese.year().cyclic().unwrap().get(), 40);
311314
/// assert_eq!(date_chinese.year().related_iso(), Some(2023));
312315
/// assert_eq!(date_chinese.month().ordinal, 6);
313316
/// assert_eq!(date_chinese.day_of_month().0, 11);
314317
/// ```
315318
pub fn try_new_chinese_with_calendar(
316-
year: i32,
319+
related_iso_year: i32,
317320
month: u8,
318321
day: u8,
319322
calendar: A,
320323
) -> Result<Date<A>, DateError> {
321324
let year = calendar
322325
.as_calendar()
323326
.get_precomputed_data()
324-
.load_or_compute_info(year);
327+
.load_or_compute_info(related_iso_year);
325328
let arithmetic = Inner::new_from_ordinals(year, month, day);
326329
Ok(Date::from_raw(
327330
ChineseDateInner(ChineseBasedDateInner(arithmetic?)),
@@ -456,23 +459,25 @@ mod test {
456459
let chinese_cached = Chinese::new();
457460
for case in cases {
458461
let rata_die = RataDie::new(case.rd);
459-
let iso = Iso.from_rata_die(rata_die);
460462

461463
do_twice(
462464
&chinese_calculating,
463465
&chinese_cached,
464466
|chinese, calendar_type| {
465-
let chinese = Inner::chinese_based_date_from_rd(chinese.0, rata_die, iso.0);
467+
let chinese = Date::from_rata_die(rata_die, chinese);
466468
assert_eq!(
467-
case.expected_year, chinese.0.year.value,
469+
case.expected_year,
470+
chinese.year().extended_year,
468471
"[{calendar_type}] Chinese from RD failed, case: {case:?}"
469472
);
470473
assert_eq!(
471-
case.expected_month, chinese.0.month,
474+
case.expected_month,
475+
chinese.month().ordinal,
472476
"[{calendar_type}] Chinese from RD failed, case: {case:?}"
473477
);
474478
assert_eq!(
475-
case.expected_day, chinese.0.day,
479+
case.expected_day,
480+
chinese.day_of_month().0,
476481
"[{calendar_type}] Chinese from RD failed, case: {case:?}"
477482
);
478483
},
@@ -492,14 +497,14 @@ mod test {
492497

493498
let cases = [
494499
TestCase {
495-
year: 4660,
500+
year: 2023,
496501
month: 6,
497502
day: 6,
498503
// June 23 2023
499504
expected: 738694,
500505
},
501506
TestCase {
502-
year: 1,
507+
year: -2636,
503508
month: 1,
504509
day: 1,
505510
expected: -963099,
@@ -562,7 +567,7 @@ mod test {
562567
|chinese, _calendar_type| {
563568
let chinese = iso.to_calendar(chinese);
564569

565-
assert_eq!(chinese.year().era_year_or_extended(), 1);
570+
assert_eq!(chinese.year().era_year_or_related_iso(), -2636);
566571
assert_eq!(chinese.month().ordinal, 1);
567572
assert_eq!(chinese.month().standard_code.0, "M01");
568573
assert_eq!(chinese.day_of_month().0, 1);
@@ -589,15 +594,15 @@ mod test {
589594
iso_year: -2636,
590595
iso_month: 2,
591596
iso_day: 14,
592-
expected_year: 0,
597+
expected_year: -2637,
593598
expected_month: 13,
594599
expected_day: 30,
595600
},
596601
TestCase {
597602
iso_year: -2636,
598603
iso_month: 1,
599604
iso_day: 15,
600-
expected_year: 0,
605+
expected_year: -2637,
601606
expected_month: 12,
602607
expected_day: 30,
603608
},
@@ -615,7 +620,7 @@ mod test {
615620
let chinese = iso.to_calendar(chinese);
616621
assert_eq!(
617622
case.expected_year,
618-
chinese.year().era_year_or_extended(),
623+
chinese.year().era_year_or_related_iso(),
619624
"[{calendar_type}] ISO to Chinese failed for case: {case:?}"
620625
);
621626
assert_eq!(
@@ -674,10 +679,9 @@ mod test {
674679

675680
#[test]
676681
fn test_month_days() {
677-
let year = 4660;
678682
let year =
679683
ChineseBasedPrecomputedData::<<Chinese as ChineseBasedWithDataLoading>::CB>::default()
680-
.load_or_compute_info(year);
684+
.load_or_compute_info(2023);
681685
let cases = [
682686
(1, 29),
683687
(2, 30),
@@ -831,7 +835,7 @@ mod test {
831835
// construct using ::default() to force recomputation
832836
let year =
833837
ChineseBasedPrecomputedData::<<Chinese as ChineseBasedWithDataLoading>::CB>::default()
834-
.load_or_compute_info(4660);
838+
.load_or_compute_info(2023);
835839
let codes = [
836840
(1, tinystr!(4, "M01")),
837841
(2, tinystr!(4, "M02")),
@@ -854,7 +858,7 @@ mod test {
854858
ordinal,
855859
Some(ordinal_code_pair.0),
856860
"Code to ordinal failed for year: {}, code: {code}",
857-
year.value
861+
year.related_iso
858862
);
859863
}
860864
}
@@ -884,7 +888,7 @@ mod test {
884888
assert_eq!(
885889
ordinal, None,
886890
"Invalid month code failed for year: {}, code: {code}",
887-
year.value
891+
year.related_iso
888892
);
889893
}
890894
}

0 commit comments

Comments
 (0)