/rust/registry/src/index.crates.io-6f17d22bba15001f/icu_calendar-1.5.2/src/indian.rs
Line | Count | Source (jump to first uncovered line) |
1 | | // This file is part of ICU4X. For terms of use, please see the file |
2 | | // called LICENSE at the top level of the ICU4X source tree |
3 | | // (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ). |
4 | | |
5 | | //! This module contains types and implementations for the Indian national calendar. |
6 | | //! |
7 | | //! ```rust |
8 | | //! use icu::calendar::{indian::Indian, Date, DateTime}; |
9 | | //! |
10 | | //! // `Date` type |
11 | | //! let date_iso = Date::try_new_iso_date(1970, 1, 2) |
12 | | //! .expect("Failed to initialize ISO Date instance."); |
13 | | //! let date_indian = Date::new_from_iso(date_iso, Indian); |
14 | | //! |
15 | | //! // `DateTime` type |
16 | | //! let datetime_iso = DateTime::try_new_iso_datetime(1970, 1, 2, 13, 1, 0) |
17 | | //! .expect("Failed to initialize ISO DateTime instance."); |
18 | | //! let datetime_indian = DateTime::new_from_iso(datetime_iso, Indian); |
19 | | //! |
20 | | //! // `Date` checks |
21 | | //! assert_eq!(date_indian.year().number, 1891); |
22 | | //! assert_eq!(date_indian.month().ordinal, 10); |
23 | | //! assert_eq!(date_indian.day_of_month().0, 12); |
24 | | //! |
25 | | //! // `DateTime` type |
26 | | //! assert_eq!(datetime_indian.date.year().number, 1891); |
27 | | //! assert_eq!(datetime_indian.date.month().ordinal, 10); |
28 | | //! assert_eq!(datetime_indian.date.day_of_month().0, 12); |
29 | | //! assert_eq!(datetime_indian.time.hour.number(), 13); |
30 | | //! assert_eq!(datetime_indian.time.minute.number(), 1); |
31 | | //! assert_eq!(datetime_indian.time.second.number(), 0); |
32 | | //! ``` |
33 | | |
34 | | use crate::any_calendar::AnyCalendarKind; |
35 | | use crate::calendar_arithmetic::{ArithmeticDate, CalendarArithmetic}; |
36 | | use crate::iso::Iso; |
37 | | use crate::{types, Calendar, CalendarError, Date, DateDuration, DateDurationUnit, DateTime, Time}; |
38 | | use tinystr::tinystr; |
39 | | |
40 | | /// The Indian National Calendar (aka the Saka calendar) |
41 | | /// |
42 | | /// The [Indian National calendar] is a solar calendar used by the Indian government, with twelve months. |
43 | | /// |
44 | | /// This type can be used with [`Date`] or [`DateTime`] to represent dates in this calendar. |
45 | | /// |
46 | | /// [Indian National calendar]: https://en.wikipedia.org/wiki/Indian_national_calendar |
47 | | /// |
48 | | /// # Era codes |
49 | | /// |
50 | | /// This calendar has a single era: `"saka"`, with Saka 0 being 78 CE. Dates before this era use negative years. |
51 | | /// |
52 | | /// # Month codes |
53 | | /// |
54 | | /// This calendar supports 12 solar month codes (`"M01" - "M12"`) |
55 | | #[derive(Copy, Clone, Debug, Hash, Default, Eq, PartialEq, PartialOrd, Ord)] |
56 | | #[allow(clippy::exhaustive_structs)] // this type is stable |
57 | | pub struct Indian; |
58 | | |
59 | | /// The inner date type used for representing [`Date`]s of [`Indian`]. See [`Date`] and [`Indian`] for more details. |
60 | | #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq, PartialOrd, Ord)] |
61 | | pub struct IndianDateInner(ArithmeticDate<Indian>); |
62 | | |
63 | | impl CalendarArithmetic for Indian { |
64 | | type YearInfo = (); |
65 | | |
66 | 0 | fn month_days(year: i32, month: u8, _data: ()) -> u8 { |
67 | 0 | if month == 1 { |
68 | 0 | if Self::is_leap_year(year, ()) { |
69 | 0 | 31 |
70 | | } else { |
71 | 0 | 30 |
72 | | } |
73 | 0 | } else if (2..=6).contains(&month) { |
74 | 0 | 31 |
75 | 0 | } else if (7..=12).contains(&month) { |
76 | 0 | 30 |
77 | | } else { |
78 | 0 | 0 |
79 | | } |
80 | 0 | } |
81 | | |
82 | 0 | fn months_for_every_year(_: i32, _data: ()) -> u8 { |
83 | 0 | 12 |
84 | 0 | } |
85 | | |
86 | 0 | fn is_leap_year(year: i32, _data: ()) -> bool { |
87 | 0 | Iso::is_leap_year(year + 78, ()) |
88 | 0 | } |
89 | | |
90 | 0 | fn last_month_day_in_year(_year: i32, _data: ()) -> (u8, u8) { |
91 | 0 | (12, 30) |
92 | 0 | } |
93 | | |
94 | 0 | fn days_in_provided_year(year: i32, _data: ()) -> u16 { |
95 | 0 | if Self::is_leap_year(year, ()) { |
96 | 0 | 366 |
97 | | } else { |
98 | 0 | 365 |
99 | | } |
100 | 0 | } |
101 | | } |
102 | | |
103 | | /// The Saka calendar starts on the 81st day of the Gregorian year (March 22 or 21) |
104 | | /// which is an 80 day offset. This number should be subtracted from Gregorian dates |
105 | | const DAY_OFFSET: u16 = 80; |
106 | | /// The Saka calendar is 78 years behind Gregorian. This number should be added to Gregorian dates |
107 | | const YEAR_OFFSET: i32 = 78; |
108 | | |
109 | | impl Calendar for Indian { |
110 | | type DateInner = IndianDateInner; |
111 | 0 | fn date_from_codes( |
112 | 0 | &self, |
113 | 0 | era: types::Era, |
114 | 0 | year: i32, |
115 | 0 | month_code: types::MonthCode, |
116 | 0 | day: u8, |
117 | 0 | ) -> Result<Self::DateInner, CalendarError> { |
118 | 0 | if era.0 != tinystr!(16, "saka") && era.0 != tinystr!(16, "indian") { |
119 | 0 | return Err(CalendarError::UnknownEra(era.0, self.debug_name())); |
120 | 0 | } |
121 | 0 |
|
122 | 0 | ArithmeticDate::new_from_codes(self, year, month_code, day).map(IndianDateInner) |
123 | 0 | } |
124 | | |
125 | | // Algorithms directly implemented in icu_calendar since they're not from the book |
126 | 0 | fn date_from_iso(&self, iso: Date<Iso>) -> IndianDateInner { |
127 | 0 | // Get day number in year (1 indexed) |
128 | 0 | let day_of_year_iso = Iso::day_of_year(*iso.inner()); |
129 | 0 | // Convert to Saka year |
130 | 0 | let mut year = iso.inner().0.year - YEAR_OFFSET; |
131 | | // This is in the previous Indian year |
132 | 0 | let day_of_year_indian = if day_of_year_iso <= DAY_OFFSET { |
133 | 0 | year -= 1; |
134 | 0 | let n_days = Self::days_in_provided_year(year, ()); |
135 | 0 |
|
136 | 0 | // calculate day of year in previous year |
137 | 0 | n_days + day_of_year_iso - DAY_OFFSET |
138 | | } else { |
139 | 0 | day_of_year_iso - DAY_OFFSET |
140 | | }; |
141 | 0 | IndianDateInner(ArithmeticDate::date_from_year_day( |
142 | 0 | year, |
143 | 0 | day_of_year_indian as u32, |
144 | 0 | )) |
145 | 0 | } |
146 | | |
147 | | // Algorithms directly implemented in icu_calendar since they're not from the book |
148 | 0 | fn date_to_iso(&self, date: &Self::DateInner) -> Date<Iso> { |
149 | 0 | let day_of_year_indian = date.0.day_of_year(); |
150 | 0 | let days_in_year = date.0.days_in_year(); |
151 | 0 |
|
152 | 0 | let mut year = date.0.year + YEAR_OFFSET; |
153 | 0 | let day_of_year_iso = if day_of_year_indian + DAY_OFFSET >= days_in_year { |
154 | 0 | year += 1; |
155 | 0 | // calculate day of year in next year |
156 | 0 | day_of_year_indian + DAY_OFFSET - days_in_year |
157 | | } else { |
158 | 0 | day_of_year_indian + DAY_OFFSET |
159 | | }; |
160 | | |
161 | 0 | Iso::iso_from_year_day(year, day_of_year_iso) |
162 | 0 | } |
163 | | |
164 | 0 | fn months_in_year(&self, date: &Self::DateInner) -> u8 { |
165 | 0 | date.0.months_in_year() |
166 | 0 | } |
167 | | |
168 | 0 | fn days_in_year(&self, date: &Self::DateInner) -> u16 { |
169 | 0 | date.0.days_in_year() |
170 | 0 | } |
171 | | |
172 | 0 | fn days_in_month(&self, date: &Self::DateInner) -> u8 { |
173 | 0 | date.0.days_in_month() |
174 | 0 | } |
175 | | |
176 | 0 | fn day_of_week(&self, date: &Self::DateInner) -> types::IsoWeekday { |
177 | 0 | Iso.day_of_week(Indian.date_to_iso(date).inner()) |
178 | 0 | } |
179 | | |
180 | 0 | fn offset_date(&self, date: &mut Self::DateInner, offset: DateDuration<Self>) { |
181 | 0 | date.0.offset_date(offset, &()); |
182 | 0 | } |
183 | | |
184 | | #[allow(clippy::field_reassign_with_default)] |
185 | 0 | fn until( |
186 | 0 | &self, |
187 | 0 | date1: &Self::DateInner, |
188 | 0 | date2: &Self::DateInner, |
189 | 0 | _calendar2: &Self, |
190 | 0 | _largest_unit: DateDurationUnit, |
191 | 0 | _smallest_unit: DateDurationUnit, |
192 | 0 | ) -> DateDuration<Self> { |
193 | 0 | date1.0.until(date2.0, _largest_unit, _smallest_unit) |
194 | 0 | } |
195 | | |
196 | 0 | fn year(&self, date: &Self::DateInner) -> types::FormattableYear { |
197 | 0 | types::FormattableYear { |
198 | 0 | era: types::Era(tinystr!(16, "saka")), |
199 | 0 | number: date.0.year, |
200 | 0 | cyclic: None, |
201 | 0 | related_iso: None, |
202 | 0 | } |
203 | 0 | } |
204 | | |
205 | 0 | fn is_in_leap_year(&self, date: &Self::DateInner) -> bool { |
206 | 0 | Self::is_leap_year(date.0.year, ()) |
207 | 0 | } |
208 | | |
209 | 0 | fn month(&self, date: &Self::DateInner) -> types::FormattableMonth { |
210 | 0 | date.0.month() |
211 | 0 | } |
212 | | |
213 | 0 | fn day_of_month(&self, date: &Self::DateInner) -> types::DayOfMonth { |
214 | 0 | date.0.day_of_month() |
215 | 0 | } |
216 | | |
217 | 0 | fn day_of_year_info(&self, date: &Self::DateInner) -> types::DayOfYearInfo { |
218 | 0 | let prev_year = types::FormattableYear { |
219 | 0 | era: types::Era(tinystr!(16, "saka")), |
220 | 0 | number: date.0.year - 1, |
221 | 0 | cyclic: None, |
222 | 0 | related_iso: None, |
223 | 0 | }; |
224 | 0 | let next_year = types::FormattableYear { |
225 | 0 | era: types::Era(tinystr!(16, "saka")), |
226 | 0 | number: date.0.year + 1, |
227 | 0 | cyclic: None, |
228 | 0 | related_iso: None, |
229 | 0 | }; |
230 | 0 | types::DayOfYearInfo { |
231 | 0 | day_of_year: date.0.day_of_year(), |
232 | 0 | days_in_year: date.0.days_in_year(), |
233 | 0 | prev_year, |
234 | 0 | days_in_prev_year: Indian::days_in_year_direct(date.0.year - 1), |
235 | 0 | next_year, |
236 | 0 | } |
237 | 0 | } |
238 | | |
239 | 0 | fn debug_name(&self) -> &'static str { |
240 | 0 | "Indian" |
241 | 0 | } |
242 | | |
243 | 0 | fn any_calendar_kind(&self) -> Option<AnyCalendarKind> { |
244 | 0 | Some(AnyCalendarKind::Indian) |
245 | 0 | } |
246 | | } |
247 | | |
248 | | impl Indian { |
249 | | /// Construct a new Indian Calendar |
250 | 0 | pub fn new() -> Self { |
251 | 0 | Self |
252 | 0 | } |
253 | | |
254 | 0 | fn days_in_year_direct(year: i32) -> u16 { |
255 | 0 | if Indian::is_leap_year(year, ()) { |
256 | 0 | 366 |
257 | | } else { |
258 | 0 | 365 |
259 | | } |
260 | 0 | } |
261 | | } |
262 | | |
263 | | impl Date<Indian> { |
264 | | /// Construct new Indian Date, with year provided in the Śaka era. |
265 | | /// |
266 | | /// ```rust |
267 | | /// use icu::calendar::Date; |
268 | | /// |
269 | | /// let date_indian = Date::try_new_indian_date(1891, 10, 12) |
270 | | /// .expect("Failed to initialize Indian Date instance."); |
271 | | /// |
272 | | /// assert_eq!(date_indian.year().number, 1891); |
273 | | /// assert_eq!(date_indian.month().ordinal, 10); |
274 | | /// assert_eq!(date_indian.day_of_month().0, 12); |
275 | | /// ``` |
276 | 0 | pub fn try_new_indian_date( |
277 | 0 | year: i32, |
278 | 0 | month: u8, |
279 | 0 | day: u8, |
280 | 0 | ) -> Result<Date<Indian>, CalendarError> { |
281 | 0 | ArithmeticDate::new_from_ordinals(year, month, day) |
282 | 0 | .map(IndianDateInner) |
283 | 0 | .map(|inner| Date::from_raw(inner, Indian)) |
284 | 0 | } |
285 | | } |
286 | | |
287 | | impl DateTime<Indian> { |
288 | | /// Construct a new Indian datetime from integers, with year provided in the Śaka era. |
289 | | /// |
290 | | /// ```rust |
291 | | /// use icu::calendar::DateTime; |
292 | | /// |
293 | | /// let datetime_indian = |
294 | | /// DateTime::try_new_indian_datetime(1891, 10, 12, 13, 1, 0) |
295 | | /// .expect("Failed to initialize Indian DateTime instance."); |
296 | | /// |
297 | | /// assert_eq!(datetime_indian.date.year().number, 1891); |
298 | | /// assert_eq!(datetime_indian.date.month().ordinal, 10); |
299 | | /// assert_eq!(datetime_indian.date.day_of_month().0, 12); |
300 | | /// assert_eq!(datetime_indian.time.hour.number(), 13); |
301 | | /// assert_eq!(datetime_indian.time.minute.number(), 1); |
302 | | /// assert_eq!(datetime_indian.time.second.number(), 0); |
303 | | /// ``` |
304 | 0 | pub fn try_new_indian_datetime( |
305 | 0 | year: i32, |
306 | 0 | month: u8, |
307 | 0 | day: u8, |
308 | 0 | hour: u8, |
309 | 0 | minute: u8, |
310 | 0 | second: u8, |
311 | 0 | ) -> Result<DateTime<Indian>, CalendarError> { |
312 | 0 | Ok(DateTime { |
313 | 0 | date: Date::try_new_indian_date(year, month, day)?, |
314 | 0 | time: Time::try_new(hour, minute, second, 0)?, |
315 | | }) |
316 | 0 | } |
317 | | } |
318 | | |
319 | | #[cfg(test)] |
320 | | mod tests { |
321 | | use super::*; |
322 | | use calendrical_calculations::rata_die::RataDie; |
323 | | fn assert_roundtrip(y: i32, m: u8, d: u8, iso_y: i32, iso_m: u8, iso_d: u8) { |
324 | | let indian = |
325 | | Date::try_new_indian_date(y, m, d).expect("Indian date should construct successfully"); |
326 | | let iso = indian.to_iso(); |
327 | | |
328 | | assert_eq!( |
329 | | iso.year().number, |
330 | | iso_y, |
331 | | "{y}-{m}-{d}: ISO year did not match" |
332 | | ); |
333 | | assert_eq!( |
334 | | iso.month().ordinal as u8, |
335 | | iso_m, |
336 | | "{y}-{m}-{d}: ISO month did not match" |
337 | | ); |
338 | | assert_eq!( |
339 | | iso.day_of_month().0 as u8, |
340 | | iso_d, |
341 | | "{y}-{m}-{d}: ISO day did not match" |
342 | | ); |
343 | | |
344 | | let roundtrip = iso.to_calendar(Indian); |
345 | | |
346 | | assert_eq!( |
347 | | roundtrip.year().number, |
348 | | indian.year().number, |
349 | | "{y}-{m}-{d}: roundtrip year did not match" |
350 | | ); |
351 | | assert_eq!( |
352 | | roundtrip.month().ordinal, |
353 | | indian.month().ordinal, |
354 | | "{y}-{m}-{d}: roundtrip month did not match" |
355 | | ); |
356 | | assert_eq!( |
357 | | roundtrip.day_of_month(), |
358 | | indian.day_of_month(), |
359 | | "{y}-{m}-{d}: roundtrip day did not match" |
360 | | ); |
361 | | } |
362 | | |
363 | | #[test] |
364 | | fn roundtrip_indian() { |
365 | | // Ultimately the day of the year will always be identical regardless of it |
366 | | // being a leap year or not |
367 | | // Test dates that occur after and before Chaitra 1 (March 22/21), in all years of |
368 | | // a four-year leap cycle, to ensure that all code paths are tested |
369 | | assert_roundtrip(1944, 6, 7, 2022, 8, 29); |
370 | | assert_roundtrip(1943, 6, 7, 2021, 8, 29); |
371 | | assert_roundtrip(1942, 6, 7, 2020, 8, 29); |
372 | | assert_roundtrip(1941, 6, 7, 2019, 8, 29); |
373 | | assert_roundtrip(1944, 11, 7, 2023, 1, 27); |
374 | | assert_roundtrip(1943, 11, 7, 2022, 1, 27); |
375 | | assert_roundtrip(1942, 11, 7, 2021, 1, 27); |
376 | | assert_roundtrip(1941, 11, 7, 2020, 1, 27); |
377 | | } |
378 | | |
379 | | #[derive(Debug)] |
380 | | struct TestCase { |
381 | | iso_year: i32, |
382 | | iso_month: u8, |
383 | | iso_day: u8, |
384 | | expected_year: i32, |
385 | | expected_month: u32, |
386 | | expected_day: u32, |
387 | | } |
388 | | |
389 | | fn check_case(case: TestCase) { |
390 | | let iso = Date::try_new_iso_date(case.iso_year, case.iso_month, case.iso_day).unwrap(); |
391 | | let saka = iso.to_calendar(Indian); |
392 | | assert_eq!( |
393 | | saka.year().number, |
394 | | case.expected_year, |
395 | | "Year check failed for case: {case:?}" |
396 | | ); |
397 | | assert_eq!( |
398 | | saka.month().ordinal, |
399 | | case.expected_month, |
400 | | "Month check failed for case: {case:?}" |
401 | | ); |
402 | | assert_eq!( |
403 | | saka.day_of_month().0, |
404 | | case.expected_day, |
405 | | "Day check failed for case: {case:?}" |
406 | | ); |
407 | | } |
408 | | |
409 | | #[test] |
410 | | fn test_cases_near_epoch_start() { |
411 | | let cases = [ |
412 | | TestCase { |
413 | | iso_year: 79, |
414 | | iso_month: 3, |
415 | | iso_day: 23, |
416 | | expected_year: 1, |
417 | | expected_month: 1, |
418 | | expected_day: 2, |
419 | | }, |
420 | | TestCase { |
421 | | iso_year: 79, |
422 | | iso_month: 3, |
423 | | iso_day: 22, |
424 | | expected_year: 1, |
425 | | expected_month: 1, |
426 | | expected_day: 1, |
427 | | }, |
428 | | TestCase { |
429 | | iso_year: 79, |
430 | | iso_month: 3, |
431 | | iso_day: 21, |
432 | | expected_year: 0, |
433 | | expected_month: 12, |
434 | | expected_day: 30, |
435 | | }, |
436 | | TestCase { |
437 | | iso_year: 79, |
438 | | iso_month: 3, |
439 | | iso_day: 20, |
440 | | expected_year: 0, |
441 | | expected_month: 12, |
442 | | expected_day: 29, |
443 | | }, |
444 | | TestCase { |
445 | | iso_year: 78, |
446 | | iso_month: 3, |
447 | | iso_day: 21, |
448 | | expected_year: -1, |
449 | | expected_month: 12, |
450 | | expected_day: 30, |
451 | | }, |
452 | | ]; |
453 | | |
454 | | for case in cases { |
455 | | check_case(case); |
456 | | } |
457 | | } |
458 | | |
459 | | #[test] |
460 | | fn test_cases_near_rd_zero() { |
461 | | let cases = [ |
462 | | TestCase { |
463 | | iso_year: 1, |
464 | | iso_month: 3, |
465 | | iso_day: 22, |
466 | | expected_year: -77, |
467 | | expected_month: 1, |
468 | | expected_day: 1, |
469 | | }, |
470 | | TestCase { |
471 | | iso_year: 1, |
472 | | iso_month: 3, |
473 | | iso_day: 21, |
474 | | expected_year: -78, |
475 | | expected_month: 12, |
476 | | expected_day: 30, |
477 | | }, |
478 | | TestCase { |
479 | | iso_year: 1, |
480 | | iso_month: 1, |
481 | | iso_day: 1, |
482 | | expected_year: -78, |
483 | | expected_month: 10, |
484 | | expected_day: 11, |
485 | | }, |
486 | | TestCase { |
487 | | iso_year: 0, |
488 | | iso_month: 3, |
489 | | iso_day: 21, |
490 | | expected_year: -78, |
491 | | expected_month: 1, |
492 | | expected_day: 1, |
493 | | }, |
494 | | TestCase { |
495 | | iso_year: 0, |
496 | | iso_month: 1, |
497 | | iso_day: 1, |
498 | | expected_year: -79, |
499 | | expected_month: 10, |
500 | | expected_day: 11, |
501 | | }, |
502 | | TestCase { |
503 | | iso_year: -1, |
504 | | iso_month: 3, |
505 | | iso_day: 21, |
506 | | expected_year: -80, |
507 | | expected_month: 12, |
508 | | expected_day: 30, |
509 | | }, |
510 | | ]; |
511 | | |
512 | | for case in cases { |
513 | | check_case(case); |
514 | | } |
515 | | } |
516 | | |
517 | | #[test] |
518 | | fn test_roundtrip_near_rd_zero() { |
519 | | for i in -1000..=1000 { |
520 | | let initial = RataDie::new(i); |
521 | | let result = Iso::fixed_from_iso( |
522 | | Iso::iso_from_fixed(initial) |
523 | | .to_calendar(Indian) |
524 | | .to_calendar(Iso) |
525 | | .inner, |
526 | | ); |
527 | | assert_eq!( |
528 | | initial, result, |
529 | | "Roundtrip failed for initial: {initial:?}, result: {result:?}" |
530 | | ); |
531 | | } |
532 | | } |
533 | | |
534 | | #[test] |
535 | | fn test_roundtrip_near_epoch_start() { |
536 | | // Epoch start: RD 28570 |
537 | | for i in 27570..=29570 { |
538 | | let initial = RataDie::new(i); |
539 | | let result = Iso::fixed_from_iso( |
540 | | Iso::iso_from_fixed(initial) |
541 | | .to_calendar(Indian) |
542 | | .to_calendar(Iso) |
543 | | .inner, |
544 | | ); |
545 | | assert_eq!( |
546 | | initial, result, |
547 | | "Roundtrip failed for initial: {initial:?}, result: {result:?}" |
548 | | ); |
549 | | } |
550 | | } |
551 | | |
552 | | #[test] |
553 | | fn test_directionality_near_rd_zero() { |
554 | | for i in -100..=100 { |
555 | | for j in -100..=100 { |
556 | | let rd_i = RataDie::new(i); |
557 | | let rd_j = RataDie::new(j); |
558 | | |
559 | | let indian_i = Iso::iso_from_fixed(rd_i).to_calendar(Indian); |
560 | | let indian_j = Iso::iso_from_fixed(rd_j).to_calendar(Indian); |
561 | | |
562 | | assert_eq!(i.cmp(&j), indian_i.cmp(&indian_j), "Directionality test failed for i: {i}, j: {j}, indian_i: {indian_i:?}, indian_j: {indian_j:?}"); |
563 | | } |
564 | | } |
565 | | } |
566 | | |
567 | | #[test] |
568 | | fn test_directionality_near_epoch_start() { |
569 | | // Epoch start: RD 28570 |
570 | | for i in 28470..=28670 { |
571 | | for j in 28470..=28670 { |
572 | | let indian_i = Iso::iso_from_fixed(RataDie::new(i)).to_calendar(Indian); |
573 | | let indian_j = Iso::iso_from_fixed(RataDie::new(j)).to_calendar(Indian); |
574 | | |
575 | | assert_eq!(i.cmp(&j), indian_i.cmp(&indian_j), "Directionality test failed for i: {i}, j: {j}, indian_i: {indian_i:?}, indian_j: {indian_j:?}"); |
576 | | } |
577 | | } |
578 | | } |
579 | | } |