Skip to content

Commit 95a7211

Browse files
committed
rd is slightly cheaper for Indian
1 parent c666a29 commit 95a7211

File tree

1 file changed

+12
-28
lines changed

1 file changed

+12
-28
lines changed

components/calendar/src/cal/indian.rs

Lines changed: 12 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
// called LICENSE at the top level of the ICU4X source tree
33
// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).
44

5-
use crate::cal::iso::{Iso, IsoDateInner};
65
use crate::calendar_arithmetic::ArithmeticDate;
76
use crate::calendar_arithmetic::{ArithmeticDateBuilder, DateFieldsResolver};
87
use crate::error::{DateError, DateFromFieldsError, EcmaReferenceYearError, UnknownEraError};
@@ -112,24 +111,14 @@ impl Calendar for Indian {
112111
Ok(IndianDateInner(arithmetic_date))
113112
}
114113

115-
fn from_rata_die(&self, rd: RataDie) -> Self::DateInner {
116-
self.from_iso(Iso.from_rata_die(rd))
117-
}
118-
119-
fn to_rata_die(&self, date: &Self::DateInner) -> RataDie {
120-
Iso.to_rata_die(&self.to_iso(date))
121-
}
122-
123-
const HAS_CHEAP_ISO_CONVERSION: bool = true;
124-
125114
// Algorithms directly implemented in icu_calendar since they're not from the book
126-
fn from_iso(&self, iso: IsoDateInner) -> IndianDateInner {
115+
fn from_rata_die(&self, rd: RataDie) -> Self::DateInner {
116+
let iso_year = calendrical_calculations::gregorian::year_from_fixed(rd).unwrap_or(i32::MIN);
127117
// Get day number in year (1 indexed)
128118
let day_of_year_iso =
129-
calendrical_calculations::gregorian::days_before_month(iso.0.year, iso.0.month)
130-
+ iso.0.day as u16;
119+
(rd - calendrical_calculations::gregorian::day_before_year(iso_year)) as u16;
131120
// Convert to Śaka year
132-
let mut year = iso.0.year - YEAR_OFFSET;
121+
let mut year = iso_year - YEAR_OFFSET;
133122
// This is in the previous Indian year
134123
let day_of_year_indian = if day_of_year_iso <= DAY_OFFSET {
135124
year -= 1;
@@ -163,24 +152,25 @@ impl Calendar for Indian {
163152
}
164153

165154
// Algorithms directly implemented in icu_calendar since they're not from the book
166-
fn to_iso(&self, date: &Self::DateInner) -> IsoDateInner {
155+
fn to_rata_die(&self, date: &Self::DateInner) -> RataDie {
167156
let day_of_year_indian = self.day_of_year(date).0; // 1-indexed
168157
let days_in_year = self.days_in_year(date);
169158

170-
let mut year = date.0.year + YEAR_OFFSET;
159+
let mut year_iso = date.0.year + YEAR_OFFSET;
171160
// days_in_year is a valid day of the year, so we check > not >=
172161
let day_of_year_iso = if day_of_year_indian + DAY_OFFSET > days_in_year {
173-
year += 1;
162+
year_iso += 1;
174163
// calculate day of year in next year
175164
day_of_year_indian + DAY_OFFSET - days_in_year
176165
} else {
177166
day_of_year_indian + DAY_OFFSET
178167
};
179168

180-
let (month, day) = calendrical_calculations::gregorian::year_day(year, day_of_year_iso);
181-
IsoDateInner(ArithmeticDate::new_unchecked(year, month, day))
169+
calendrical_calculations::gregorian::day_before_year(year_iso) + day_of_year_iso as i64
182170
}
183171

172+
const HAS_CHEAP_ISO_CONVERSION: bool = false;
173+
184174
fn months_in_year(&self, date: &Self::DateInner) -> u8 {
185175
Self::months_in_provided_year(date.0.year)
186176
}
@@ -485,10 +475,7 @@ mod tests {
485475
fn test_roundtrip_near_rd_zero() {
486476
for i in -1000..=1000 {
487477
let initial = RataDie::new(i);
488-
let result = Date::from_rata_die(initial, Iso)
489-
.to_calendar(Indian)
490-
.to_iso()
491-
.to_rata_die();
478+
let result = Date::from_rata_die(initial, Indian).to_rata_die();
492479
assert_eq!(
493480
initial, result,
494481
"Roundtrip failed for initial: {initial:?}, result: {result:?}"
@@ -501,10 +488,7 @@ mod tests {
501488
// Epoch start: RD 28570
502489
for i in 27570..=29570 {
503490
let initial = RataDie::new(i);
504-
let result = Date::from_rata_die(initial, Iso)
505-
.to_calendar(Indian)
506-
.to_iso()
507-
.to_rata_die();
491+
let result = Date::from_rata_die(initial, Indian).to_rata_die();
508492
assert_eq!(
509493
initial, result,
510494
"Roundtrip failed for initial: {initial:?}, result: {result:?}"

0 commit comments

Comments
 (0)