/rust/registry/src/index.crates.io-6f17d22bba15001f/icu_calendar-1.5.2/src/persian.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 Persian calendar. |
6 | | //! |
7 | | //! ```rust |
8 | | //! use icu::calendar::{Date, DateTime}; |
9 | | //! |
10 | | //! // `Date` type |
11 | | //! let persian_date = Date::try_new_persian_date(1348, 10, 11) |
12 | | //! .expect("Failed to initialize Persian Date instance."); |
13 | | //! |
14 | | //! // `DateTime` type |
15 | | //! let persian_datetime = |
16 | | //! DateTime::try_new_persian_datetime(1348, 10, 11, 13, 1, 0) |
17 | | //! .expect("Failed to initialize Persian DateTime instance."); |
18 | | //! |
19 | | //! // `Date` checks |
20 | | //! assert_eq!(persian_date.year().number, 1348); |
21 | | //! assert_eq!(persian_date.month().ordinal, 10); |
22 | | //! assert_eq!(persian_date.day_of_month().0, 11); |
23 | | //! |
24 | | //! // `DateTime` checks |
25 | | //! assert_eq!(persian_datetime.date.year().number, 1348); |
26 | | //! assert_eq!(persian_datetime.date.month().ordinal, 10); |
27 | | //! assert_eq!(persian_datetime.date.day_of_month().0, 11); |
28 | | //! assert_eq!(persian_datetime.time.hour.number(), 13); |
29 | | //! assert_eq!(persian_datetime.time.minute.number(), 1); |
30 | | //! assert_eq!(persian_datetime.time.second.number(), 0); |
31 | | //! ``` |
32 | | |
33 | | use crate::any_calendar::AnyCalendarKind; |
34 | | use crate::calendar_arithmetic::{ArithmeticDate, CalendarArithmetic}; |
35 | | use crate::iso::Iso; |
36 | | use crate::{types, Calendar, CalendarError, Date, DateDuration, DateDurationUnit, DateTime, Time}; |
37 | | use ::tinystr::tinystr; |
38 | | use calendrical_calculations::helpers::I32CastError; |
39 | | use calendrical_calculations::rata_die::RataDie; |
40 | | |
41 | | /// The Persian Calendar |
42 | | /// |
43 | | /// The [Persian Calendar] is a solar calendar used officially by the countries of Iran and Afghanistan and many Persian-speaking regions. |
44 | | /// It has 12 months and other similarities to the Gregorian Calendar |
45 | | /// |
46 | | /// This type can be used with [`Date`] or [`DateTime`] to represent dates in this calendar. |
47 | | /// |
48 | | /// [Persian Calendar]: https://en.wikipedia.org/wiki/Solar_Hijri_calendar |
49 | | /// |
50 | | /// # Era codes |
51 | | /// |
52 | | /// This calendar supports only one era code, which starts from the year of the Hijra, designated as "ah". |
53 | | /// |
54 | | /// # Month codes |
55 | | /// |
56 | | /// This calendar supports 12 solar month codes (`"M01" - "M12"`) |
57 | | #[derive(Copy, Clone, Debug, Default, Hash, Eq, PartialEq, PartialOrd, Ord)] |
58 | | #[allow(clippy::exhaustive_structs)] |
59 | | pub struct Persian; |
60 | | |
61 | | #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq, PartialOrd, Ord)] |
62 | | |
63 | | /// The inner date type used for representing [`Date`]s of [`Persian`]. See [`Date`] and [`Persian`] for more details. |
64 | | pub struct PersianDateInner(ArithmeticDate<Persian>); |
65 | | |
66 | | impl CalendarArithmetic for Persian { |
67 | | type YearInfo = (); |
68 | | |
69 | 0 | fn month_days(year: i32, month: u8, _data: ()) -> u8 { |
70 | 0 | match month { |
71 | 0 | 1..=6 => 31, |
72 | 0 | 7..=11 => 30, |
73 | 0 | 12 if Self::is_leap_year(year, ()) => 30, |
74 | 0 | 12 => 29, |
75 | 0 | _ => 0, |
76 | | } |
77 | 0 | } |
78 | | |
79 | 0 | fn months_for_every_year(_: i32, _data: ()) -> u8 { |
80 | 0 | 12 |
81 | 0 | } |
82 | | |
83 | 0 | fn is_leap_year(p_year: i32, _data: ()) -> bool { |
84 | 0 | calendrical_calculations::persian::is_leap_year(p_year, _data) |
85 | 0 | } |
86 | | |
87 | 0 | fn days_in_provided_year(year: i32, _data: ()) -> u16 { |
88 | 0 | if Self::is_leap_year(year, ()) { |
89 | 0 | 366 |
90 | | } else { |
91 | 0 | 365 |
92 | | } |
93 | 0 | } |
94 | | |
95 | 0 | fn last_month_day_in_year(year: i32, _data: ()) -> (u8, u8) { |
96 | 0 | if Self::is_leap_year(year, ()) { |
97 | 0 | (12, 30) |
98 | | } else { |
99 | 0 | (12, 29) |
100 | | } |
101 | 0 | } |
102 | | } |
103 | | |
104 | | impl Calendar for Persian { |
105 | | type DateInner = PersianDateInner; |
106 | 0 | fn date_from_codes( |
107 | 0 | &self, |
108 | 0 | era: types::Era, |
109 | 0 | year: i32, |
110 | 0 | month_code: types::MonthCode, |
111 | 0 | day: u8, |
112 | 0 | ) -> Result<Self::DateInner, CalendarError> { |
113 | 0 | let year = if era.0 == tinystr!(16, "ah") || era.0 == tinystr!(16, "persian") { |
114 | 0 | year |
115 | | } else { |
116 | 0 | return Err(CalendarError::UnknownEra(era.0, self.debug_name())); |
117 | | }; |
118 | | |
119 | 0 | ArithmeticDate::new_from_codes(self, year, month_code, day).map(PersianDateInner) |
120 | 0 | } |
121 | | |
122 | 0 | fn date_from_iso(&self, iso: Date<Iso>) -> PersianDateInner { |
123 | 0 | let fixed_iso = Iso::fixed_from_iso(*iso.inner()); |
124 | 0 | Self::fast_persian_from_fixed(fixed_iso) |
125 | 0 | } |
126 | | |
127 | 0 | fn date_to_iso(&self, date: &Self::DateInner) -> Date<Iso> { |
128 | 0 | let fixed_persian = Persian::fixed_from_fast_persian(*date); |
129 | 0 | Iso::iso_from_fixed(fixed_persian) |
130 | 0 | } |
131 | | |
132 | 0 | fn months_in_year(&self, date: &Self::DateInner) -> u8 { |
133 | 0 | date.0.months_in_year() |
134 | 0 | } |
135 | | |
136 | 0 | fn days_in_year(&self, date: &Self::DateInner) -> u16 { |
137 | 0 | date.0.days_in_year() |
138 | 0 | } |
139 | | |
140 | 0 | fn days_in_month(&self, date: &Self::DateInner) -> u8 { |
141 | 0 | date.0.days_in_month() |
142 | 0 | } |
143 | | |
144 | 0 | fn day_of_week(&self, date: &Self::DateInner) -> types::IsoWeekday { |
145 | 0 | Iso.day_of_week(self.date_to_iso(date).inner()) |
146 | 0 | } |
147 | | |
148 | 0 | fn offset_date(&self, date: &mut Self::DateInner, offset: DateDuration<Self>) { |
149 | 0 | date.0.offset_date(offset, &()) |
150 | 0 | } |
151 | | |
152 | | #[allow(clippy::field_reassign_with_default)] |
153 | 0 | fn until( |
154 | 0 | &self, |
155 | 0 | date1: &Self::DateInner, |
156 | 0 | date2: &Self::DateInner, |
157 | 0 | _calendar2: &Self, |
158 | 0 | _largest_unit: DateDurationUnit, |
159 | 0 | _smallest_unit: DateDurationUnit, |
160 | 0 | ) -> DateDuration<Self> { |
161 | 0 | date1.0.until(date2.0, _largest_unit, _smallest_unit) |
162 | 0 | } |
163 | | |
164 | 0 | fn year(&self, date: &Self::DateInner) -> types::FormattableYear { |
165 | 0 | Self::year_as_persian(date.0.year) |
166 | 0 | } |
167 | | |
168 | 0 | fn is_in_leap_year(&self, date: &Self::DateInner) -> bool { |
169 | 0 | Self::is_leap_year(date.0.year, ()) |
170 | 0 | } |
171 | | |
172 | 0 | fn month(&self, date: &Self::DateInner) -> types::FormattableMonth { |
173 | 0 | date.0.month() |
174 | 0 | } |
175 | | |
176 | 0 | fn day_of_month(&self, date: &Self::DateInner) -> types::DayOfMonth { |
177 | 0 | date.0.day_of_month() |
178 | 0 | } |
179 | | |
180 | 0 | fn day_of_year_info(&self, date: &Self::DateInner) -> types::DayOfYearInfo { |
181 | 0 | let prev_year = date.0.year.saturating_sub(1); |
182 | 0 | let next_year = date.0.year.saturating_add(1); |
183 | 0 | types::DayOfYearInfo { |
184 | 0 | day_of_year: date.0.day_of_year(), |
185 | 0 | days_in_year: date.0.days_in_year(), |
186 | 0 | prev_year: Persian::year_as_persian(prev_year), |
187 | 0 | days_in_prev_year: Persian::days_in_provided_year(prev_year, ()), |
188 | 0 | next_year: Persian::year_as_persian(next_year), |
189 | 0 | } |
190 | 0 | } |
191 | | |
192 | 0 | fn debug_name(&self) -> &'static str { |
193 | 0 | "Persian" |
194 | 0 | } |
195 | | // Missing any_calendar persian tests, the rest is completed |
196 | 0 | fn any_calendar_kind(&self) -> Option<AnyCalendarKind> { |
197 | 0 | Some(AnyCalendarKind::Persian) |
198 | 0 | } |
199 | | } |
200 | | |
201 | | impl Persian { |
202 | | /// Constructs a new Persian Calendar |
203 | 0 | pub fn new() -> Self { |
204 | 0 | Self |
205 | 0 | } |
206 | | |
207 | 0 | fn fixed_from_fast_persian(p_date: PersianDateInner) -> RataDie { |
208 | 0 | calendrical_calculations::persian::fixed_from_fast_persian( |
209 | 0 | p_date.0.year, |
210 | 0 | p_date.0.month, |
211 | 0 | p_date.0.day, |
212 | 0 | ) |
213 | 0 | } |
214 | 0 | fn fast_persian_from_fixed(date: RataDie) -> PersianDateInner { |
215 | 0 | let (year, month, day) = |
216 | 0 | match calendrical_calculations::persian::fast_persian_from_fixed(date) { |
217 | 0 | Err(I32CastError::BelowMin) => return PersianDateInner(ArithmeticDate::min_date()), |
218 | 0 | Err(I32CastError::AboveMax) => return PersianDateInner(ArithmeticDate::max_date()), |
219 | 0 | Ok(ymd) => ymd, |
220 | 0 | }; |
221 | 0 |
|
222 | 0 | PersianDateInner(ArithmeticDate::new_unchecked(year, month, day)) |
223 | 0 | } |
224 | | |
225 | 0 | fn year_as_persian(year: i32) -> types::FormattableYear { |
226 | 0 | types::FormattableYear { |
227 | 0 | era: types::Era(tinystr!(16, "ah")), |
228 | 0 | number: year, |
229 | 0 | cyclic: None, |
230 | 0 | related_iso: None, |
231 | 0 | } |
232 | 0 | } |
233 | | } |
234 | | |
235 | | impl Date<Persian> { |
236 | | /// Construct new Persian Date. |
237 | | /// |
238 | | /// Has no negative years, only era is the AH/AP. |
239 | | /// |
240 | | /// ```rust |
241 | | /// use icu::calendar::Date; |
242 | | /// |
243 | | /// let date_persian = Date::try_new_persian_date(1392, 4, 25) |
244 | | /// .expect("Failed to initialize Persian Date instance."); |
245 | | /// |
246 | | /// assert_eq!(date_persian.year().number, 1392); |
247 | | /// assert_eq!(date_persian.month().ordinal, 4); |
248 | | /// assert_eq!(date_persian.day_of_month().0, 25); |
249 | | /// ``` |
250 | 0 | pub fn try_new_persian_date( |
251 | 0 | year: i32, |
252 | 0 | month: u8, |
253 | 0 | day: u8, |
254 | 0 | ) -> Result<Date<Persian>, CalendarError> { |
255 | 0 | ArithmeticDate::new_from_ordinals(year, month, day) |
256 | 0 | .map(PersianDateInner) |
257 | 0 | .map(|inner| Date::from_raw(inner, Persian)) |
258 | 0 | } |
259 | | } |
260 | | |
261 | | impl DateTime<Persian> { |
262 | | /// Construct a new Persian datetime from integers. |
263 | | /// |
264 | | /// ```rust |
265 | | /// use icu::calendar::DateTime; |
266 | | /// |
267 | | /// let datetime_persian = |
268 | | /// DateTime::try_new_persian_datetime(474, 10, 11, 13, 1, 0) |
269 | | /// .expect("Failed to initialize Persian DateTime instance."); |
270 | | /// |
271 | | /// assert_eq!(datetime_persian.date.year().number, 474); |
272 | | /// assert_eq!(datetime_persian.date.month().ordinal, 10); |
273 | | /// assert_eq!(datetime_persian.date.day_of_month().0, 11); |
274 | | /// assert_eq!(datetime_persian.time.hour.number(), 13); |
275 | | /// assert_eq!(datetime_persian.time.minute.number(), 1); |
276 | | /// assert_eq!(datetime_persian.time.second.number(), 0); |
277 | | /// ``` |
278 | 0 | pub fn try_new_persian_datetime( |
279 | 0 | year: i32, |
280 | 0 | month: u8, |
281 | 0 | day: u8, |
282 | 0 | hour: u8, |
283 | 0 | minute: u8, |
284 | 0 | second: u8, |
285 | 0 | ) -> Result<DateTime<Persian>, CalendarError> { |
286 | 0 | Ok(DateTime { |
287 | 0 | date: Date::try_new_persian_date(year, month, day)?, |
288 | 0 | time: Time::try_new(hour, minute, second, 0)?, |
289 | | }) |
290 | 0 | } |
291 | | } |
292 | | |
293 | | #[cfg(test)] |
294 | | mod tests { |
295 | | use super::*; |
296 | | #[derive(Debug)] |
297 | | struct DateCase { |
298 | | year: i32, |
299 | | month: u8, |
300 | | day: u8, |
301 | | } |
302 | | |
303 | | static TEST_FIXED_DATE: [i64; 21] = [ |
304 | | 656786, 664224, 671401, 694799, 702806, 704424, 708842, 709409, 709580, 727274, 728714, |
305 | | 739330, 739331, 744313, 763436, 763437, 764652, 775123, 775488, 775489, 1317874, |
306 | | ]; |
307 | | |
308 | | // Test data are provided for the range 1178-3000 AP, for which |
309 | | // we know the 33-year rule, with the override table, matches the |
310 | | // astronomical calculations based on the 52.5 degrees east meridian. |
311 | | static CASES: [DateCase; 21] = [ |
312 | | // First year for which 33-year rule matches the astronomical calculation |
313 | | DateCase { |
314 | | year: 1178, |
315 | | month: 1, |
316 | | day: 1, |
317 | | }, |
318 | | DateCase { |
319 | | year: 1198, |
320 | | month: 5, |
321 | | day: 10, |
322 | | }, |
323 | | DateCase { |
324 | | year: 1218, |
325 | | month: 1, |
326 | | day: 7, |
327 | | }, |
328 | | DateCase { |
329 | | year: 1282, |
330 | | month: 1, |
331 | | day: 29, |
332 | | }, |
333 | | // The beginning of the year the calendar was adopted |
334 | | DateCase { |
335 | | year: 1304, |
336 | | month: 1, |
337 | | day: 1, |
338 | | }, |
339 | | DateCase { |
340 | | year: 1308, |
341 | | month: 6, |
342 | | day: 3, |
343 | | }, |
344 | | DateCase { |
345 | | year: 1320, |
346 | | month: 7, |
347 | | day: 7, |
348 | | }, |
349 | | DateCase { |
350 | | year: 1322, |
351 | | month: 1, |
352 | | day: 29, |
353 | | }, |
354 | | DateCase { |
355 | | year: 1322, |
356 | | month: 7, |
357 | | day: 14, |
358 | | }, |
359 | | DateCase { |
360 | | year: 1370, |
361 | | month: 12, |
362 | | day: 27, |
363 | | }, |
364 | | DateCase { |
365 | | year: 1374, |
366 | | month: 12, |
367 | | day: 6, |
368 | | }, |
369 | | // First day that the 2820-year rule fails |
370 | | DateCase { |
371 | | year: 1403, |
372 | | month: 12, |
373 | | day: 30, |
374 | | }, |
375 | | // First Nowruz that the 2820-year rule fails |
376 | | DateCase { |
377 | | year: 1404, |
378 | | month: 1, |
379 | | day: 1, |
380 | | }, |
381 | | DateCase { |
382 | | year: 1417, |
383 | | month: 8, |
384 | | day: 19, |
385 | | }, |
386 | | // First day the unmodified astronomical algorithm fails |
387 | | DateCase { |
388 | | year: 1469, |
389 | | month: 12, |
390 | | day: 30, |
391 | | }, |
392 | | // First Nowruz the unmodified astronomical algorithm fails |
393 | | DateCase { |
394 | | year: 1470, |
395 | | month: 1, |
396 | | day: 1, |
397 | | }, |
398 | | DateCase { |
399 | | year: 1473, |
400 | | month: 4, |
401 | | day: 28, |
402 | | }, |
403 | | // Last year the 33-year rule matches the modified astronomical calculation |
404 | | DateCase { |
405 | | year: 1501, |
406 | | month: 12, |
407 | | day: 29, |
408 | | }, |
409 | | DateCase { |
410 | | year: 1502, |
411 | | month: 12, |
412 | | day: 29, |
413 | | }, |
414 | | DateCase { |
415 | | year: 1503, |
416 | | month: 1, |
417 | | day: 1, |
418 | | }, |
419 | | DateCase { |
420 | | year: 2988, |
421 | | month: 1, |
422 | | day: 1, |
423 | | }, |
424 | | ]; |
425 | | |
426 | | fn days_in_provided_year_core(year: i32) -> u16 { |
427 | | let fixed_year = |
428 | | calendrical_calculations::persian::fixed_from_fast_persian(year, 1, 1).to_i64_date(); |
429 | | let next_fixed_year = |
430 | | calendrical_calculations::persian::fixed_from_fast_persian(year + 1, 1, 1) |
431 | | .to_i64_date(); |
432 | | |
433 | | (next_fixed_year - fixed_year) as u16 |
434 | | } |
435 | | |
436 | | #[test] |
437 | | fn test_persian_leap_year() { |
438 | | let mut leap_years: [i32; 21] = [0; 21]; |
439 | | // These values were computed from the "Calendrical Calculations" reference code output |
440 | | let expected_values = [ |
441 | | false, false, true, false, true, false, false, false, false, true, false, true, false, |
442 | | false, true, false, false, false, false, true, true, |
443 | | ]; |
444 | | |
445 | | for (index, case) in CASES.iter().enumerate() { |
446 | | leap_years[index] = case.year; |
447 | | } |
448 | | for (year, bool) in leap_years.iter().zip(expected_values.iter()) { |
449 | | assert_eq!(Persian::is_leap_year(*year, ()), *bool); |
450 | | } |
451 | | } |
452 | | |
453 | | #[test] |
454 | | fn days_in_provided_year_test() { |
455 | | for case in CASES.iter() { |
456 | | assert_eq!( |
457 | | days_in_provided_year_core(case.year), |
458 | | Persian::days_in_provided_year(case.year, ()) |
459 | | ); |
460 | | } |
461 | | } |
462 | | |
463 | | #[test] |
464 | | fn test_fixed_from_persian() { |
465 | | for (case, f_date) in CASES.iter().zip(TEST_FIXED_DATE.iter()) { |
466 | | let date = Date::try_new_persian_date(case.year, case.month, case.day).unwrap(); |
467 | | |
468 | | assert_eq!( |
469 | | Persian::fixed_from_fast_persian(*date.inner()).to_i64_date(), |
470 | | *f_date, |
471 | | "{case:?}" |
472 | | ); |
473 | | } |
474 | | } |
475 | | #[test] |
476 | | fn test_persian_from_fixed() { |
477 | | for (case, f_date) in CASES.iter().zip(TEST_FIXED_DATE.iter()) { |
478 | | let date = Date::try_new_persian_date(case.year, case.month, case.day).unwrap(); |
479 | | assert_eq!( |
480 | | Persian::fast_persian_from_fixed(RataDie::new(*f_date)), |
481 | | date.inner, |
482 | | "{case:?}" |
483 | | ); |
484 | | } |
485 | | } |
486 | | |
487 | | #[test] |
488 | | fn test_day_of_year_info() { |
489 | | #[derive(Debug)] |
490 | | struct TestCase { |
491 | | input: i32, |
492 | | expected_prev: i32, |
493 | | expected_next: i32, |
494 | | } |
495 | | |
496 | | let test_cases = [ |
497 | | TestCase { |
498 | | input: 0, |
499 | | expected_prev: -1, |
500 | | expected_next: 1, |
501 | | }, |
502 | | TestCase { |
503 | | input: i32::MAX, |
504 | | expected_prev: i32::MAX - 1, |
505 | | expected_next: i32::MAX, // can't go above i32::MAX |
506 | | }, |
507 | | TestCase { |
508 | | input: i32::MIN + 1, |
509 | | expected_prev: i32::MIN, |
510 | | expected_next: i32::MIN + 2, |
511 | | }, |
512 | | TestCase { |
513 | | input: i32::MIN, |
514 | | expected_prev: i32::MIN, // can't go below i32::MIN |
515 | | expected_next: i32::MIN + 1, |
516 | | }, |
517 | | ]; |
518 | | |
519 | | for case in test_cases { |
520 | | let date = Date::try_new_persian_date(case.input, 1, 1).unwrap(); |
521 | | let info = Persian::day_of_year_info(&Persian, date.inner()); |
522 | | |
523 | | assert_eq!(info.prev_year.number, case.expected_prev, "{:?}", case); |
524 | | assert_eq!(info.next_year.number, case.expected_next, "{:?}", case); |
525 | | } |
526 | | } |
527 | | |
528 | | // From https://calendar.ut.ac.ir/Fa/News/Data/Doc/KabiseShamsi1206-1498-new.pdf |
529 | | // Plain text version at https://github.com/roozbehp/persiancalendar/blob/main/kabise.txt |
530 | | static CALENDAR_UT_AC_IR_TEST_DATA: [(i32, bool, i32, u32, u32); 293] = [ |
531 | | (1206, false, 1827, 3, 22), |
532 | | (1207, false, 1828, 3, 21), |
533 | | (1208, false, 1829, 3, 21), |
534 | | (1209, false, 1830, 3, 21), |
535 | | (1210, true, 1831, 3, 21), |
536 | | (1211, false, 1832, 3, 21), |
537 | | (1212, false, 1833, 3, 21), |
538 | | (1213, false, 1834, 3, 21), |
539 | | (1214, true, 1835, 3, 21), |
540 | | (1215, false, 1836, 3, 21), |
541 | | (1216, false, 1837, 3, 21), |
542 | | (1217, false, 1838, 3, 21), |
543 | | (1218, true, 1839, 3, 21), |
544 | | (1219, false, 1840, 3, 21), |
545 | | (1220, false, 1841, 3, 21), |
546 | | (1221, false, 1842, 3, 21), |
547 | | (1222, true, 1843, 3, 21), |
548 | | (1223, false, 1844, 3, 21), |
549 | | (1224, false, 1845, 3, 21), |
550 | | (1225, false, 1846, 3, 21), |
551 | | (1226, true, 1847, 3, 21), |
552 | | (1227, false, 1848, 3, 21), |
553 | | (1228, false, 1849, 3, 21), |
554 | | (1229, false, 1850, 3, 21), |
555 | | (1230, true, 1851, 3, 21), |
556 | | (1231, false, 1852, 3, 21), |
557 | | (1232, false, 1853, 3, 21), |
558 | | (1233, false, 1854, 3, 21), |
559 | | (1234, true, 1855, 3, 21), |
560 | | (1235, false, 1856, 3, 21), |
561 | | (1236, false, 1857, 3, 21), |
562 | | (1237, false, 1858, 3, 21), |
563 | | (1238, true, 1859, 3, 21), |
564 | | (1239, false, 1860, 3, 21), |
565 | | (1240, false, 1861, 3, 21), |
566 | | (1241, false, 1862, 3, 21), |
567 | | (1242, false, 1863, 3, 21), |
568 | | (1243, true, 1864, 3, 20), |
569 | | (1244, false, 1865, 3, 21), |
570 | | (1245, false, 1866, 3, 21), |
571 | | (1246, false, 1867, 3, 21), |
572 | | (1247, true, 1868, 3, 20), |
573 | | (1248, false, 1869, 3, 21), |
574 | | (1249, false, 1870, 3, 21), |
575 | | (1250, false, 1871, 3, 21), |
576 | | (1251, true, 1872, 3, 20), |
577 | | (1252, false, 1873, 3, 21), |
578 | | (1253, false, 1874, 3, 21), |
579 | | (1254, false, 1875, 3, 21), |
580 | | (1255, true, 1876, 3, 20), |
581 | | (1256, false, 1877, 3, 21), |
582 | | (1257, false, 1878, 3, 21), |
583 | | (1258, false, 1879, 3, 21), |
584 | | (1259, true, 1880, 3, 20), |
585 | | (1260, false, 1881, 3, 21), |
586 | | (1261, false, 1882, 3, 21), |
587 | | (1262, false, 1883, 3, 21), |
588 | | (1263, true, 1884, 3, 20), |
589 | | (1264, false, 1885, 3, 21), |
590 | | (1265, false, 1886, 3, 21), |
591 | | (1266, false, 1887, 3, 21), |
592 | | (1267, true, 1888, 3, 20), |
593 | | (1268, false, 1889, 3, 21), |
594 | | (1269, false, 1890, 3, 21), |
595 | | (1270, false, 1891, 3, 21), |
596 | | (1271, true, 1892, 3, 20), |
597 | | (1272, false, 1893, 3, 21), |
598 | | (1273, false, 1894, 3, 21), |
599 | | (1274, false, 1895, 3, 21), |
600 | | (1275, false, 1896, 3, 20), |
601 | | (1276, true, 1897, 3, 20), |
602 | | (1277, false, 1898, 3, 21), |
603 | | (1278, false, 1899, 3, 21), |
604 | | (1279, false, 1900, 3, 21), |
605 | | (1280, true, 1901, 3, 21), |
606 | | (1281, false, 1902, 3, 22), |
607 | | (1282, false, 1903, 3, 22), |
608 | | (1283, false, 1904, 3, 21), |
609 | | (1284, true, 1905, 3, 21), |
610 | | (1285, false, 1906, 3, 22), |
611 | | (1286, false, 1907, 3, 22), |
612 | | (1287, false, 1908, 3, 21), |
613 | | (1288, true, 1909, 3, 21), |
614 | | (1289, false, 1910, 3, 22), |
615 | | (1290, false, 1911, 3, 22), |
616 | | (1291, false, 1912, 3, 21), |
617 | | (1292, true, 1913, 3, 21), |
618 | | (1293, false, 1914, 3, 22), |
619 | | (1294, false, 1915, 3, 22), |
620 | | (1295, false, 1916, 3, 21), |
621 | | (1296, true, 1917, 3, 21), |
622 | | (1297, false, 1918, 3, 22), |
623 | | (1298, false, 1919, 3, 22), |
624 | | (1299, false, 1920, 3, 21), |
625 | | (1300, true, 1921, 3, 21), |
626 | | (1301, false, 1922, 3, 22), |
627 | | (1302, false, 1923, 3, 22), |
628 | | (1303, false, 1924, 3, 21), |
629 | | (1304, true, 1925, 3, 21), |
630 | | (1305, false, 1926, 3, 22), |
631 | | (1306, false, 1927, 3, 22), |
632 | | (1307, false, 1928, 3, 21), |
633 | | (1308, false, 1929, 3, 21), |
634 | | (1309, true, 1930, 3, 21), |
635 | | (1310, false, 1931, 3, 22), |
636 | | (1311, false, 1932, 3, 21), |
637 | | (1312, false, 1933, 3, 21), |
638 | | (1313, true, 1934, 3, 21), |
639 | | (1314, false, 1935, 3, 22), |
640 | | (1315, false, 1936, 3, 21), |
641 | | (1316, false, 1937, 3, 21), |
642 | | (1317, true, 1938, 3, 21), |
643 | | (1318, false, 1939, 3, 22), |
644 | | (1319, false, 1940, 3, 21), |
645 | | (1320, false, 1941, 3, 21), |
646 | | (1321, true, 1942, 3, 21), |
647 | | (1322, false, 1943, 3, 22), |
648 | | (1323, false, 1944, 3, 21), |
649 | | (1324, false, 1945, 3, 21), |
650 | | (1325, true, 1946, 3, 21), |
651 | | (1326, false, 1947, 3, 22), |
652 | | (1327, false, 1948, 3, 21), |
653 | | (1328, false, 1949, 3, 21), |
654 | | (1329, true, 1950, 3, 21), |
655 | | (1330, false, 1951, 3, 22), |
656 | | (1331, false, 1952, 3, 21), |
657 | | (1332, false, 1953, 3, 21), |
658 | | (1333, true, 1954, 3, 21), |
659 | | (1334, false, 1955, 3, 22), |
660 | | (1335, false, 1956, 3, 21), |
661 | | (1336, false, 1957, 3, 21), |
662 | | (1337, true, 1958, 3, 21), |
663 | | (1338, false, 1959, 3, 22), |
664 | | (1339, false, 1960, 3, 21), |
665 | | (1340, false, 1961, 3, 21), |
666 | | (1341, false, 1962, 3, 21), |
667 | | (1342, true, 1963, 3, 21), |
668 | | (1343, false, 1964, 3, 21), |
669 | | (1344, false, 1965, 3, 21), |
670 | | (1345, false, 1966, 3, 21), |
671 | | (1346, true, 1967, 3, 21), |
672 | | (1347, false, 1968, 3, 21), |
673 | | (1348, false, 1969, 3, 21), |
674 | | (1349, false, 1970, 3, 21), |
675 | | (1350, true, 1971, 3, 21), |
676 | | (1351, false, 1972, 3, 21), |
677 | | (1352, false, 1973, 3, 21), |
678 | | (1353, false, 1974, 3, 21), |
679 | | (1354, true, 1975, 3, 21), |
680 | | (1355, false, 1976, 3, 21), |
681 | | (1356, false, 1977, 3, 21), |
682 | | (1357, false, 1978, 3, 21), |
683 | | (1358, true, 1979, 3, 21), |
684 | | (1359, false, 1980, 3, 21), |
685 | | (1360, false, 1981, 3, 21), |
686 | | (1361, false, 1982, 3, 21), |
687 | | (1362, true, 1983, 3, 21), |
688 | | (1363, false, 1984, 3, 21), |
689 | | (1364, false, 1985, 3, 21), |
690 | | (1365, false, 1986, 3, 21), |
691 | | (1366, true, 1987, 3, 21), |
692 | | (1367, false, 1988, 3, 21), |
693 | | (1368, false, 1989, 3, 21), |
694 | | (1369, false, 1990, 3, 21), |
695 | | (1370, true, 1991, 3, 21), |
696 | | (1371, false, 1992, 3, 21), |
697 | | (1372, false, 1993, 3, 21), |
698 | | (1373, false, 1994, 3, 21), |
699 | | (1374, false, 1995, 3, 21), |
700 | | (1375, true, 1996, 3, 20), |
701 | | (1376, false, 1997, 3, 21), |
702 | | (1377, false, 1998, 3, 21), |
703 | | (1378, false, 1999, 3, 21), |
704 | | (1379, true, 2000, 3, 20), |
705 | | (1380, false, 2001, 3, 21), |
706 | | (1381, false, 2002, 3, 21), |
707 | | (1382, false, 2003, 3, 21), |
708 | | (1383, true, 2004, 3, 20), |
709 | | (1384, false, 2005, 3, 21), |
710 | | (1385, false, 2006, 3, 21), |
711 | | (1386, false, 2007, 3, 21), |
712 | | (1387, true, 2008, 3, 20), |
713 | | (1388, false, 2009, 3, 21), |
714 | | (1389, false, 2010, 3, 21), |
715 | | (1390, false, 2011, 3, 21), |
716 | | (1391, true, 2012, 3, 20), |
717 | | (1392, false, 2013, 3, 21), |
718 | | (1393, false, 2014, 3, 21), |
719 | | (1394, false, 2015, 3, 21), |
720 | | (1395, true, 2016, 3, 20), |
721 | | (1396, false, 2017, 3, 21), |
722 | | (1397, false, 2018, 3, 21), |
723 | | (1398, false, 2019, 3, 21), |
724 | | (1399, true, 2020, 3, 20), |
725 | | (1400, false, 2021, 3, 21), |
726 | | (1401, false, 2022, 3, 21), |
727 | | (1402, false, 2023, 3, 21), |
728 | | (1403, true, 2024, 3, 20), |
729 | | (1404, false, 2025, 3, 21), |
730 | | (1405, false, 2026, 3, 21), |
731 | | (1406, false, 2027, 3, 21), |
732 | | (1407, false, 2028, 3, 20), |
733 | | (1408, true, 2029, 3, 20), |
734 | | (1409, false, 2030, 3, 21), |
735 | | (1410, false, 2031, 3, 21), |
736 | | (1411, false, 2032, 3, 20), |
737 | | (1412, true, 2033, 3, 20), |
738 | | (1413, false, 2034, 3, 21), |
739 | | (1414, false, 2035, 3, 21), |
740 | | (1415, false, 2036, 3, 20), |
741 | | (1416, true, 2037, 3, 20), |
742 | | (1417, false, 2038, 3, 21), |
743 | | (1418, false, 2039, 3, 21), |
744 | | (1419, false, 2040, 3, 20), |
745 | | (1420, true, 2041, 3, 20), |
746 | | (1421, false, 2042, 3, 21), |
747 | | (1422, false, 2043, 3, 21), |
748 | | (1423, false, 2044, 3, 20), |
749 | | (1424, true, 2045, 3, 20), |
750 | | (1425, false, 2046, 3, 21), |
751 | | (1426, false, 2047, 3, 21), |
752 | | (1427, false, 2048, 3, 20), |
753 | | (1428, true, 2049, 3, 20), |
754 | | (1429, false, 2050, 3, 21), |
755 | | (1430, false, 2051, 3, 21), |
756 | | (1431, false, 2052, 3, 20), |
757 | | (1432, true, 2053, 3, 20), |
758 | | (1433, false, 2054, 3, 21), |
759 | | (1434, false, 2055, 3, 21), |
760 | | (1435, false, 2056, 3, 20), |
761 | | (1436, true, 2057, 3, 20), |
762 | | (1437, false, 2058, 3, 21), |
763 | | (1438, false, 2059, 3, 21), |
764 | | (1439, false, 2060, 3, 20), |
765 | | (1440, false, 2061, 3, 20), |
766 | | (1441, true, 2062, 3, 20), |
767 | | (1442, false, 2063, 3, 21), |
768 | | (1443, false, 2064, 3, 20), |
769 | | (1444, false, 2065, 3, 20), |
770 | | (1445, true, 2066, 3, 20), |
771 | | (1446, false, 2067, 3, 21), |
772 | | (1447, false, 2068, 3, 20), |
773 | | (1448, false, 2069, 3, 20), |
774 | | (1449, true, 2070, 3, 20), |
775 | | (1450, false, 2071, 3, 21), |
776 | | (1451, false, 2072, 3, 20), |
777 | | (1452, false, 2073, 3, 20), |
778 | | (1453, true, 2074, 3, 20), |
779 | | (1454, false, 2075, 3, 21), |
780 | | (1455, false, 2076, 3, 20), |
781 | | (1456, false, 2077, 3, 20), |
782 | | (1457, true, 2078, 3, 20), |
783 | | (1458, false, 2079, 3, 21), |
784 | | (1459, false, 2080, 3, 20), |
785 | | (1460, false, 2081, 3, 20), |
786 | | (1461, true, 2082, 3, 20), |
787 | | (1462, false, 2083, 3, 21), |
788 | | (1463, false, 2084, 3, 20), |
789 | | (1464, false, 2085, 3, 20), |
790 | | (1465, true, 2086, 3, 20), |
791 | | (1466, false, 2087, 3, 21), |
792 | | (1467, false, 2088, 3, 20), |
793 | | (1468, false, 2089, 3, 20), |
794 | | (1469, true, 2090, 3, 20), |
795 | | (1470, false, 2091, 3, 21), |
796 | | (1471, false, 2092, 3, 20), |
797 | | (1472, false, 2093, 3, 20), |
798 | | (1473, false, 2094, 3, 20), |
799 | | (1474, true, 2095, 3, 20), |
800 | | (1475, false, 2096, 3, 20), |
801 | | (1476, false, 2097, 3, 20), |
802 | | (1477, false, 2098, 3, 20), |
803 | | (1478, true, 2099, 3, 20), |
804 | | (1479, false, 2100, 3, 21), |
805 | | (1480, false, 2101, 3, 21), |
806 | | (1481, false, 2102, 3, 21), |
807 | | (1482, true, 2103, 3, 21), |
808 | | (1483, false, 2104, 3, 21), |
809 | | (1484, false, 2105, 3, 21), |
810 | | (1485, false, 2106, 3, 21), |
811 | | (1486, true, 2107, 3, 21), |
812 | | (1487, false, 2108, 3, 21), |
813 | | (1488, false, 2109, 3, 21), |
814 | | (1489, false, 2110, 3, 21), |
815 | | (1490, true, 2111, 3, 21), |
816 | | (1491, false, 2112, 3, 21), |
817 | | (1492, false, 2113, 3, 21), |
818 | | (1493, false, 2114, 3, 21), |
819 | | (1494, true, 2115, 3, 21), |
820 | | (1495, false, 2116, 3, 21), |
821 | | (1496, false, 2117, 3, 21), |
822 | | (1497, false, 2118, 3, 21), |
823 | | (1498, true, 2119, 3, 21), |
824 | | ]; |
825 | | |
826 | | #[test] |
827 | | fn test_calendar_ut_ac_ir_data() { |
828 | | for (p_year, leap, iso_year, iso_month, iso_day) in CALENDAR_UT_AC_IR_TEST_DATA.iter() { |
829 | | assert_eq!(Persian::is_leap_year(*p_year, ()), *leap); |
830 | | let persian_date = Date::try_new_persian_date(*p_year, 1, 1).unwrap(); |
831 | | let iso_date = persian_date.to_calendar(Iso); |
832 | | assert_eq!(iso_date.year().number, *iso_year); |
833 | | assert_eq!(iso_date.month().ordinal, *iso_month); |
834 | | assert_eq!(iso_date.day_of_month().0, *iso_day); |
835 | | } |
836 | | } |
837 | | } |