1use crate::any_calendar::AnyCalendarKind;
34use crate::calendar_arithmetic::{ArithmeticDate, CalendarArithmetic};
35use crate::iso::Iso;
36use crate::{types, Calendar, CalendarError, Date, DateDuration, DateDurationUnit, DateTime, Time};
37use ::tinystr::tinystr;
38use calendrical_calculations::helpers::I32CastError;
39use calendrical_calculations::rata_die::RataDie;
40
41#[derive(Copy, Clone, Debug, Default, Hash, Eq, PartialEq, PartialOrd, Ord)]
58#[allow(clippy::exhaustive_structs)]
59pub struct Persian;
60
61#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq, PartialOrd, Ord)]
62
63pub struct PersianDateInner(ArithmeticDate<Persian>);
65
66impl CalendarArithmetic for Persian {
67 type YearInfo = ();
68
69 fn month_days(year: i32, month: u8, _data: ()) -> u8 {
70 match month {
71 1..=6 => 31,
72 7..=11 => 30,
73 12 if Self::is_leap_year(year, ()) => 30,
74 12 => 29,
75 _ => 0,
76 }
77 }
78
79 fn months_for_every_year(_: i32, _data: ()) -> u8 {
80 12
81 }
82
83 fn is_leap_year(p_year: i32, _data: ()) -> bool {
84 calendrical_calculations::persian::is_leap_year(p_year, _data)
85 }
86
87 fn days_in_provided_year(year: i32, _data: ()) -> u16 {
88 if Self::is_leap_year(year, ()) {
89 366
90 } else {
91 365
92 }
93 }
94
95 fn last_month_day_in_year(year: i32, _data: ()) -> (u8, u8) {
96 if Self::is_leap_year(year, ()) {
97 (12, 30)
98 } else {
99 (12, 29)
100 }
101 }
102}
103
104impl Calendar for Persian {
105 type DateInner = PersianDateInner;
106 fn date_from_codes(
107 &self,
108 era: types::Era,
109 year: i32,
110 month_code: types::MonthCode,
111 day: u8,
112 ) -> Result<Self::DateInner, CalendarError> {
113 let year = if era.0 == tinystr!(16, "ah") || era.0 == tinystr!(16, "persian") {
114 year
115 } else {
116 return Err(CalendarError::UnknownEra(era.0, self.debug_name()));
117 };
118
119 ArithmeticDate::new_from_codes(self, year, month_code, day).map(PersianDateInner)
120 }
121
122 fn date_from_iso(&self, iso: Date<Iso>) -> PersianDateInner {
123 let fixed_iso = Iso::fixed_from_iso(*iso.inner());
124 Self::fast_persian_from_fixed(fixed_iso)
125 }
126
127 fn date_to_iso(&self, date: &Self::DateInner) -> Date<Iso> {
128 let fixed_persian = Persian::fixed_from_fast_persian(*date);
129 Iso::iso_from_fixed(fixed_persian)
130 }
131
132 fn months_in_year(&self, date: &Self::DateInner) -> u8 {
133 date.0.months_in_year()
134 }
135
136 fn days_in_year(&self, date: &Self::DateInner) -> u16 {
137 date.0.days_in_year()
138 }
139
140 fn days_in_month(&self, date: &Self::DateInner) -> u8 {
141 date.0.days_in_month()
142 }
143
144 fn day_of_week(&self, date: &Self::DateInner) -> types::IsoWeekday {
145 Iso.day_of_week(self.date_to_iso(date).inner())
146 }
147
148 fn offset_date(&self, date: &mut Self::DateInner, offset: DateDuration<Self>) {
149 date.0.offset_date(offset, &())
150 }
151
152 #[allow(clippy::field_reassign_with_default)]
153 fn until(
154 &self,
155 date1: &Self::DateInner,
156 date2: &Self::DateInner,
157 _calendar2: &Self,
158 _largest_unit: DateDurationUnit,
159 _smallest_unit: DateDurationUnit,
160 ) -> DateDuration<Self> {
161 date1.0.until(date2.0, _largest_unit, _smallest_unit)
162 }
163
164 fn year(&self, date: &Self::DateInner) -> types::FormattableYear {
165 Self::year_as_persian(date.0.year)
166 }
167
168 fn is_in_leap_year(&self, date: &Self::DateInner) -> bool {
169 Self::is_leap_year(date.0.year, ())
170 }
171
172 fn month(&self, date: &Self::DateInner) -> types::FormattableMonth {
173 date.0.month()
174 }
175
176 fn day_of_month(&self, date: &Self::DateInner) -> types::DayOfMonth {
177 date.0.day_of_month()
178 }
179
180 fn day_of_year_info(&self, date: &Self::DateInner) -> types::DayOfYearInfo {
181 let prev_year = date.0.year.saturating_sub(1);
182 let next_year = date.0.year.saturating_add(1);
183 types::DayOfYearInfo {
184 day_of_year: date.0.day_of_year(),
185 days_in_year: date.0.days_in_year(),
186 prev_year: Persian::year_as_persian(prev_year),
187 days_in_prev_year: Persian::days_in_provided_year(prev_year, ()),
188 next_year: Persian::year_as_persian(next_year),
189 }
190 }
191
192 fn debug_name(&self) -> &'static str {
193 "Persian"
194 }
195 fn any_calendar_kind(&self) -> Option<AnyCalendarKind> {
197 Some(AnyCalendarKind::Persian)
198 }
199}
200
201impl Persian {
202 pub fn new() -> Self {
204 Self
205 }
206
207 fn fixed_from_fast_persian(p_date: PersianDateInner) -> RataDie {
208 calendrical_calculations::persian::fixed_from_fast_persian(
209 p_date.0.year,
210 p_date.0.month,
211 p_date.0.day,
212 )
213 }
214 fn fast_persian_from_fixed(date: RataDie) -> PersianDateInner {
215 let (year, month, day) =
216 match calendrical_calculations::persian::fast_persian_from_fixed(date) {
217 Err(I32CastError::BelowMin) => return PersianDateInner(ArithmeticDate::min_date()),
218 Err(I32CastError::AboveMax) => return PersianDateInner(ArithmeticDate::max_date()),
219 Ok(ymd) => ymd,
220 };
221
222 PersianDateInner(ArithmeticDate::new_unchecked(year, month, day))
223 }
224
225 fn year_as_persian(year: i32) -> types::FormattableYear {
226 types::FormattableYear {
227 era: types::Era(tinystr!(16, "ah")),
228 number: year,
229 cyclic: None,
230 related_iso: None,
231 }
232 }
233}
234
235impl Date<Persian> {
236 pub fn try_new_persian_date(
251 year: i32,
252 month: u8,
253 day: u8,
254 ) -> Result<Date<Persian>, CalendarError> {
255 ArithmeticDate::new_from_ordinals(year, month, day)
256 .map(PersianDateInner)
257 .map(|inner| Date::from_raw(inner, Persian))
258 }
259}
260
261impl DateTime<Persian> {
262 pub fn try_new_persian_datetime(
279 year: i32,
280 month: u8,
281 day: u8,
282 hour: u8,
283 minute: u8,
284 second: u8,
285 ) -> Result<DateTime<Persian>, CalendarError> {
286 Ok(DateTime {
287 date: Date::try_new_persian_date(year, month, day)?,
288 time: Time::try_new(hour, minute, second, 0)?,
289 })
290 }
291}
292
293#[cfg(test)]
294mod 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 static CASES: [DateCase; 21] = [
312 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 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 DateCase {
371 year: 1403,
372 month: 12,
373 day: 30,
374 },
375 DateCase {
377 year: 1404,
378 month: 1,
379 day: 1,
380 },
381 DateCase {
382 year: 1417,
383 month: 8,
384 day: 19,
385 },
386 DateCase {
388 year: 1469,
389 month: 12,
390 day: 30,
391 },
392 DateCase {
394 year: 1470,
395 month: 1,
396 day: 1,
397 },
398 DateCase {
399 year: 1473,
400 month: 4,
401 day: 28,
402 },
403 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 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, },
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, 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 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}