1use crate::calendar_arithmetic::ArithmeticDate;
6use crate::calendar_arithmetic::DateFieldsResolver;
7use crate::error::{DateError, DateFromFieldsError, EcmaReferenceYearError, UnknownEraError};
8use crate::options::DateFromFieldsOptions;
9use crate::options::{DateAddOptions, DateDifferenceOptions};
10use crate::types::DateFields;
11use crate::{types, Calendar, Date, RangeError};
12use ::tinystr::tinystr;
13use calendrical_calculations::helpers::I32CastError;
14use calendrical_calculations::rata_die::RataDie;
15
16#[derive(Copy, Clone, Debug, Default, Hash, Eq, PartialEq, PartialOrd, Ord)]
46#[allow(clippy::exhaustive_structs)]
47pub struct Persian;
48
49#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq, PartialOrd, Ord)]
50
51pub struct PersianDateInner(ArithmeticDate<Persian>);
53
54impl DateFieldsResolver for Persian {
55 type YearInfo = i32;
56
57 fn days_in_provided_month(year: i32, month: u8) -> u8 {
58 match month {
59 1..=6 => 31,
60 7..=11 => 30,
61 12 if calendrical_calculations::persian::is_leap_year(year) => 30,
62 12 => 29,
63 _ => 0,
64 }
65 }
66
67 fn months_in_provided_year(_: i32) -> u8 {
68 12
69 }
70
71 #[inline]
72 fn year_info_from_era(
73 &self,
74 era: &[u8],
75 era_year: i32,
76 ) -> Result<Self::YearInfo, UnknownEraError> {
77 match era {
78 b"ap" => Ok(era_year),
79 _ => Err(UnknownEraError),
80 }
81 }
82
83 #[inline]
84 fn year_info_from_extended(&self, extended_year: i32) -> Self::YearInfo {
85 extended_year
86 }
87
88 #[inline]
89 fn reference_year_from_month_day(
90 &self,
91 month_code: types::ValidMonthCode,
92 day: u8,
93 ) -> Result<Self::YearInfo, EcmaReferenceYearError> {
94 let (ordinal_month, false) = month_code.to_tuple() else {
95 return Err(EcmaReferenceYearError::MonthCodeNotInCalendar);
96 };
97 let persian_year = if ordinal_month < 10 || (ordinal_month == 10 && day <= 10) {
99 1351
100 } else {
101 1350
103 };
104 Ok(persian_year)
105 }
106}
107
108impl crate::cal::scaffold::UnstableSealed for Persian {}
109impl Calendar for Persian {
110 type DateInner = PersianDateInner;
111 type Year = types::EraYear;
112 type DifferenceError = core::convert::Infallible;
113
114 fn from_codes(
115 &self,
116 era: Option<&str>,
117 year: i32,
118 month_code: types::MonthCode,
119 day: u8,
120 ) -> Result<Self::DateInner, DateError> {
121 ArithmeticDate::from_codes(era, year, month_code, day, self).map(PersianDateInner)
122 }
123
124 #[cfg(feature = "unstable")]
125 fn from_fields(
126 &self,
127 fields: DateFields,
128 options: DateFromFieldsOptions,
129 ) -> Result<Self::DateInner, DateFromFieldsError> {
130 ArithmeticDate::from_fields(fields, options, self).map(PersianDateInner)
131 }
132
133 fn from_rata_die(&self, rd: RataDie) -> Self::DateInner {
134 PersianDateInner(
135 match calendrical_calculations::persian::fast_persian_from_fixed(rd) {
136 Err(I32CastError::BelowMin) => ArithmeticDate::new_unchecked(i32::MIN, 1, 1),
137 Err(I32CastError::AboveMax) => ArithmeticDate::new_unchecked(i32::MAX, 12, 29),
138 Ok((year, month, day)) => ArithmeticDate::new_unchecked(year, month, day),
139 },
140 )
141 }
142
143 fn to_rata_die(&self, date: &Self::DateInner) -> RataDie {
144 calendrical_calculations::persian::fixed_from_fast_persian(
145 date.0.year,
146 date.0.month,
147 date.0.day,
148 )
149 }
150
151 fn has_cheap_iso_conversion(&self) -> bool {
152 false
153 }
154
155 fn months_in_year(&self, date: &Self::DateInner) -> u8 {
156 Self::months_in_provided_year(date.0.year)
157 }
158
159 fn days_in_year(&self, date: &Self::DateInner) -> u16 {
160 if self.is_in_leap_year(date) {
161 366
162 } else {
163 365
164 }
165 }
166
167 fn days_in_month(&self, date: &Self::DateInner) -> u8 {
168 Self::days_in_provided_month(date.0.year, date.0.month)
169 }
170
171 #[cfg(feature = "unstable")]
172 fn add(
173 &self,
174 date: &Self::DateInner,
175 duration: types::DateDuration,
176 options: DateAddOptions,
177 ) -> Result<Self::DateInner, DateError> {
178 date.0.added(duration, self, options).map(PersianDateInner)
179 }
180
181 #[cfg(feature = "unstable")]
182 fn until(
183 &self,
184 date1: &Self::DateInner,
185 date2: &Self::DateInner,
186 options: DateDifferenceOptions,
187 ) -> Result<types::DateDuration, Self::DifferenceError> {
188 Ok(date1.0.until(&date2.0, self, options))
189 }
190
191 fn year_info(&self, date: &Self::DateInner) -> Self::Year {
192 let extended_year = date.0.year;
193 types::EraYear {
194 era: tinystr!(16, "ap"),
195 era_index: Some(0),
196 year: extended_year,
197 extended_year,
198 ambiguity: types::YearAmbiguity::CenturyRequired,
199 }
200 }
201
202 fn is_in_leap_year(&self, date: &Self::DateInner) -> bool {
203 calendrical_calculations::persian::is_leap_year(date.0.year)
204 }
205
206 fn month(&self, date: &Self::DateInner) -> types::MonthInfo {
207 types::MonthInfo::non_lunisolar(date.0.month)
208 }
209
210 fn day_of_month(&self, date: &Self::DateInner) -> types::DayOfMonth {
211 types::DayOfMonth(date.0.day)
212 }
213
214 fn day_of_year(&self, date: &Self::DateInner) -> types::DayOfYear {
215 types::DayOfYear(
216 (date.0.month as u16 - 1) * 31 - (date.0.month as u16 - 1).saturating_sub(6)
217 + date.0.day as u16,
218 )
219 }
220
221 fn debug_name(&self) -> &'static str {
222 "Persian"
223 }
224
225 fn calendar_algorithm(&self) -> Option<crate::preferences::CalendarAlgorithm> {
226 Some(crate::preferences::CalendarAlgorithm::Persian)
227 }
228}
229
230impl Persian {
231 pub fn new() -> Self {
233 Self
234 }
235}
236
237impl Date<Persian> {
238 pub fn try_new_persian(year: i32, month: u8, day: u8) -> Result<Date<Persian>, RangeError> {
253 ArithmeticDate::try_from_ymd(year, month, day)
254 .map(PersianDateInner)
255 .map(|inner| Date::from_raw(inner, Persian))
256 }
257}
258
259#[cfg(test)]
260mod tests {
261 use super::*;
262 #[derive(Debug)]
263 struct DateCase {
264 year: i32,
265 month: u8,
266 day: u8,
267 }
268
269 static TEST_RD: [i64; 21] = [
270 656786, 664224, 671401, 694799, 702806, 704424, 708842, 709409, 709580, 727274, 728714,
271 739330, 739331, 744313, 763436, 763437, 764652, 775123, 775488, 775489, 1317874,
272 ];
273
274 static CASES: [DateCase; 21] = [
278 DateCase {
280 year: 1178,
281 month: 1,
282 day: 1,
283 },
284 DateCase {
285 year: 1198,
286 month: 5,
287 day: 10,
288 },
289 DateCase {
290 year: 1218,
291 month: 1,
292 day: 7,
293 },
294 DateCase {
295 year: 1282,
296 month: 1,
297 day: 29,
298 },
299 DateCase {
301 year: 1304,
302 month: 1,
303 day: 1,
304 },
305 DateCase {
306 year: 1308,
307 month: 6,
308 day: 3,
309 },
310 DateCase {
311 year: 1320,
312 month: 7,
313 day: 7,
314 },
315 DateCase {
316 year: 1322,
317 month: 1,
318 day: 29,
319 },
320 DateCase {
321 year: 1322,
322 month: 7,
323 day: 14,
324 },
325 DateCase {
326 year: 1370,
327 month: 12,
328 day: 27,
329 },
330 DateCase {
331 year: 1374,
332 month: 12,
333 day: 6,
334 },
335 DateCase {
337 year: 1403,
338 month: 12,
339 day: 30,
340 },
341 DateCase {
343 year: 1404,
344 month: 1,
345 day: 1,
346 },
347 DateCase {
348 year: 1417,
349 month: 8,
350 day: 19,
351 },
352 DateCase {
354 year: 1469,
355 month: 12,
356 day: 30,
357 },
358 DateCase {
360 year: 1470,
361 month: 1,
362 day: 1,
363 },
364 DateCase {
365 year: 1473,
366 month: 4,
367 day: 28,
368 },
369 DateCase {
371 year: 1501,
372 month: 12,
373 day: 29,
374 },
375 DateCase {
376 year: 1502,
377 month: 12,
378 day: 29,
379 },
380 DateCase {
381 year: 1503,
382 month: 1,
383 day: 1,
384 },
385 DateCase {
386 year: 2988,
387 month: 1,
388 day: 1,
389 },
390 ];
391
392 #[test]
393 fn test_persian_leap_year() {
394 let mut leap_years: [i32; 21] = [0; 21];
395 let expected_values = [
397 false, false, true, false, true, false, false, false, false, true, false, true, false,
398 false, true, false, false, false, false, true, true,
399 ];
400
401 for (index, case) in CASES.iter().enumerate() {
402 leap_years[index] = case.year;
403 }
404 for (&year, &is_leap) in leap_years.iter().zip(expected_values.iter()) {
405 assert_eq!(
406 Date::try_new_persian(year, 1, 1).unwrap().is_in_leap_year(),
407 is_leap
408 );
409 }
410 }
411
412 #[test]
413 fn days_in_provided_year_test() {
414 for case in CASES.iter() {
415 assert_eq!(
416 Date::try_new_persian(case.year, 1, 1)
417 .unwrap()
418 .days_in_year(),
419 (calendrical_calculations::persian::fixed_from_fast_persian(case.year + 1, 1, 1)
420 - calendrical_calculations::persian::fixed_from_fast_persian(case.year, 1, 1))
421 as u16
422 );
423 }
424 }
425
426 #[test]
427 fn test_rd_from_persian() {
428 for (case, f_date) in CASES.iter().zip(TEST_RD.iter()) {
429 let date = Date::try_new_persian(case.year, case.month, case.day).unwrap();
430
431 assert_eq!(date.to_rata_die().to_i64_date(), *f_date, "{case:?}");
432 }
433 }
434 #[test]
435 fn test_persian_from_rd() {
436 for (case, f_date) in CASES.iter().zip(TEST_RD.iter()) {
437 let date = Date::try_new_persian(case.year, case.month, case.day).unwrap();
438 assert_eq!(
439 Persian.from_rata_die(RataDie::new(*f_date)),
440 date.inner,
441 "{case:?}"
442 );
443 }
444 }
445
446 static CALENDAR_UT_AC_IR_TEST_DATA: [(i32, bool, i32, u8, u8); 293] = [
449 (1206, false, 1827, 3, 22),
450 (1207, false, 1828, 3, 21),
451 (1208, false, 1829, 3, 21),
452 (1209, false, 1830, 3, 21),
453 (1210, true, 1831, 3, 21),
454 (1211, false, 1832, 3, 21),
455 (1212, false, 1833, 3, 21),
456 (1213, false, 1834, 3, 21),
457 (1214, true, 1835, 3, 21),
458 (1215, false, 1836, 3, 21),
459 (1216, false, 1837, 3, 21),
460 (1217, false, 1838, 3, 21),
461 (1218, true, 1839, 3, 21),
462 (1219, false, 1840, 3, 21),
463 (1220, false, 1841, 3, 21),
464 (1221, false, 1842, 3, 21),
465 (1222, true, 1843, 3, 21),
466 (1223, false, 1844, 3, 21),
467 (1224, false, 1845, 3, 21),
468 (1225, false, 1846, 3, 21),
469 (1226, true, 1847, 3, 21),
470 (1227, false, 1848, 3, 21),
471 (1228, false, 1849, 3, 21),
472 (1229, false, 1850, 3, 21),
473 (1230, true, 1851, 3, 21),
474 (1231, false, 1852, 3, 21),
475 (1232, false, 1853, 3, 21),
476 (1233, false, 1854, 3, 21),
477 (1234, true, 1855, 3, 21),
478 (1235, false, 1856, 3, 21),
479 (1236, false, 1857, 3, 21),
480 (1237, false, 1858, 3, 21),
481 (1238, true, 1859, 3, 21),
482 (1239, false, 1860, 3, 21),
483 (1240, false, 1861, 3, 21),
484 (1241, false, 1862, 3, 21),
485 (1242, false, 1863, 3, 21),
486 (1243, true, 1864, 3, 20),
487 (1244, false, 1865, 3, 21),
488 (1245, false, 1866, 3, 21),
489 (1246, false, 1867, 3, 21),
490 (1247, true, 1868, 3, 20),
491 (1248, false, 1869, 3, 21),
492 (1249, false, 1870, 3, 21),
493 (1250, false, 1871, 3, 21),
494 (1251, true, 1872, 3, 20),
495 (1252, false, 1873, 3, 21),
496 (1253, false, 1874, 3, 21),
497 (1254, false, 1875, 3, 21),
498 (1255, true, 1876, 3, 20),
499 (1256, false, 1877, 3, 21),
500 (1257, false, 1878, 3, 21),
501 (1258, false, 1879, 3, 21),
502 (1259, true, 1880, 3, 20),
503 (1260, false, 1881, 3, 21),
504 (1261, false, 1882, 3, 21),
505 (1262, false, 1883, 3, 21),
506 (1263, true, 1884, 3, 20),
507 (1264, false, 1885, 3, 21),
508 (1265, false, 1886, 3, 21),
509 (1266, false, 1887, 3, 21),
510 (1267, true, 1888, 3, 20),
511 (1268, false, 1889, 3, 21),
512 (1269, false, 1890, 3, 21),
513 (1270, false, 1891, 3, 21),
514 (1271, true, 1892, 3, 20),
515 (1272, false, 1893, 3, 21),
516 (1273, false, 1894, 3, 21),
517 (1274, false, 1895, 3, 21),
518 (1275, false, 1896, 3, 20),
519 (1276, true, 1897, 3, 20),
520 (1277, false, 1898, 3, 21),
521 (1278, false, 1899, 3, 21),
522 (1279, false, 1900, 3, 21),
523 (1280, true, 1901, 3, 21),
524 (1281, false, 1902, 3, 22),
525 (1282, false, 1903, 3, 22),
526 (1283, false, 1904, 3, 21),
527 (1284, true, 1905, 3, 21),
528 (1285, false, 1906, 3, 22),
529 (1286, false, 1907, 3, 22),
530 (1287, false, 1908, 3, 21),
531 (1288, true, 1909, 3, 21),
532 (1289, false, 1910, 3, 22),
533 (1290, false, 1911, 3, 22),
534 (1291, false, 1912, 3, 21),
535 (1292, true, 1913, 3, 21),
536 (1293, false, 1914, 3, 22),
537 (1294, false, 1915, 3, 22),
538 (1295, false, 1916, 3, 21),
539 (1296, true, 1917, 3, 21),
540 (1297, false, 1918, 3, 22),
541 (1298, false, 1919, 3, 22),
542 (1299, false, 1920, 3, 21),
543 (1300, true, 1921, 3, 21),
544 (1301, false, 1922, 3, 22),
545 (1302, false, 1923, 3, 22),
546 (1303, false, 1924, 3, 21),
547 (1304, true, 1925, 3, 21),
548 (1305, false, 1926, 3, 22),
549 (1306, false, 1927, 3, 22),
550 (1307, false, 1928, 3, 21),
551 (1308, false, 1929, 3, 21),
552 (1309, true, 1930, 3, 21),
553 (1310, false, 1931, 3, 22),
554 (1311, false, 1932, 3, 21),
555 (1312, false, 1933, 3, 21),
556 (1313, true, 1934, 3, 21),
557 (1314, false, 1935, 3, 22),
558 (1315, false, 1936, 3, 21),
559 (1316, false, 1937, 3, 21),
560 (1317, true, 1938, 3, 21),
561 (1318, false, 1939, 3, 22),
562 (1319, false, 1940, 3, 21),
563 (1320, false, 1941, 3, 21),
564 (1321, true, 1942, 3, 21),
565 (1322, false, 1943, 3, 22),
566 (1323, false, 1944, 3, 21),
567 (1324, false, 1945, 3, 21),
568 (1325, true, 1946, 3, 21),
569 (1326, false, 1947, 3, 22),
570 (1327, false, 1948, 3, 21),
571 (1328, false, 1949, 3, 21),
572 (1329, true, 1950, 3, 21),
573 (1330, false, 1951, 3, 22),
574 (1331, false, 1952, 3, 21),
575 (1332, false, 1953, 3, 21),
576 (1333, true, 1954, 3, 21),
577 (1334, false, 1955, 3, 22),
578 (1335, false, 1956, 3, 21),
579 (1336, false, 1957, 3, 21),
580 (1337, true, 1958, 3, 21),
581 (1338, false, 1959, 3, 22),
582 (1339, false, 1960, 3, 21),
583 (1340, false, 1961, 3, 21),
584 (1341, false, 1962, 3, 21),
585 (1342, true, 1963, 3, 21),
586 (1343, false, 1964, 3, 21),
587 (1344, false, 1965, 3, 21),
588 (1345, false, 1966, 3, 21),
589 (1346, true, 1967, 3, 21),
590 (1347, false, 1968, 3, 21),
591 (1348, false, 1969, 3, 21),
592 (1349, false, 1970, 3, 21),
593 (1350, true, 1971, 3, 21),
594 (1351, false, 1972, 3, 21),
595 (1352, false, 1973, 3, 21),
596 (1353, false, 1974, 3, 21),
597 (1354, true, 1975, 3, 21),
598 (1355, false, 1976, 3, 21),
599 (1356, false, 1977, 3, 21),
600 (1357, false, 1978, 3, 21),
601 (1358, true, 1979, 3, 21),
602 (1359, false, 1980, 3, 21),
603 (1360, false, 1981, 3, 21),
604 (1361, false, 1982, 3, 21),
605 (1362, true, 1983, 3, 21),
606 (1363, false, 1984, 3, 21),
607 (1364, false, 1985, 3, 21),
608 (1365, false, 1986, 3, 21),
609 (1366, true, 1987, 3, 21),
610 (1367, false, 1988, 3, 21),
611 (1368, false, 1989, 3, 21),
612 (1369, false, 1990, 3, 21),
613 (1370, true, 1991, 3, 21),
614 (1371, false, 1992, 3, 21),
615 (1372, false, 1993, 3, 21),
616 (1373, false, 1994, 3, 21),
617 (1374, false, 1995, 3, 21),
618 (1375, true, 1996, 3, 20),
619 (1376, false, 1997, 3, 21),
620 (1377, false, 1998, 3, 21),
621 (1378, false, 1999, 3, 21),
622 (1379, true, 2000, 3, 20),
623 (1380, false, 2001, 3, 21),
624 (1381, false, 2002, 3, 21),
625 (1382, false, 2003, 3, 21),
626 (1383, true, 2004, 3, 20),
627 (1384, false, 2005, 3, 21),
628 (1385, false, 2006, 3, 21),
629 (1386, false, 2007, 3, 21),
630 (1387, true, 2008, 3, 20),
631 (1388, false, 2009, 3, 21),
632 (1389, false, 2010, 3, 21),
633 (1390, false, 2011, 3, 21),
634 (1391, true, 2012, 3, 20),
635 (1392, false, 2013, 3, 21),
636 (1393, false, 2014, 3, 21),
637 (1394, false, 2015, 3, 21),
638 (1395, true, 2016, 3, 20),
639 (1396, false, 2017, 3, 21),
640 (1397, false, 2018, 3, 21),
641 (1398, false, 2019, 3, 21),
642 (1399, true, 2020, 3, 20),
643 (1400, false, 2021, 3, 21),
644 (1401, false, 2022, 3, 21),
645 (1402, false, 2023, 3, 21),
646 (1403, true, 2024, 3, 20),
647 (1404, false, 2025, 3, 21),
648 (1405, false, 2026, 3, 21),
649 (1406, false, 2027, 3, 21),
650 (1407, false, 2028, 3, 20),
651 (1408, true, 2029, 3, 20),
652 (1409, false, 2030, 3, 21),
653 (1410, false, 2031, 3, 21),
654 (1411, false, 2032, 3, 20),
655 (1412, true, 2033, 3, 20),
656 (1413, false, 2034, 3, 21),
657 (1414, false, 2035, 3, 21),
658 (1415, false, 2036, 3, 20),
659 (1416, true, 2037, 3, 20),
660 (1417, false, 2038, 3, 21),
661 (1418, false, 2039, 3, 21),
662 (1419, false, 2040, 3, 20),
663 (1420, true, 2041, 3, 20),
664 (1421, false, 2042, 3, 21),
665 (1422, false, 2043, 3, 21),
666 (1423, false, 2044, 3, 20),
667 (1424, true, 2045, 3, 20),
668 (1425, false, 2046, 3, 21),
669 (1426, false, 2047, 3, 21),
670 (1427, false, 2048, 3, 20),
671 (1428, true, 2049, 3, 20),
672 (1429, false, 2050, 3, 21),
673 (1430, false, 2051, 3, 21),
674 (1431, false, 2052, 3, 20),
675 (1432, true, 2053, 3, 20),
676 (1433, false, 2054, 3, 21),
677 (1434, false, 2055, 3, 21),
678 (1435, false, 2056, 3, 20),
679 (1436, true, 2057, 3, 20),
680 (1437, false, 2058, 3, 21),
681 (1438, false, 2059, 3, 21),
682 (1439, false, 2060, 3, 20),
683 (1440, false, 2061, 3, 20),
684 (1441, true, 2062, 3, 20),
685 (1442, false, 2063, 3, 21),
686 (1443, false, 2064, 3, 20),
687 (1444, false, 2065, 3, 20),
688 (1445, true, 2066, 3, 20),
689 (1446, false, 2067, 3, 21),
690 (1447, false, 2068, 3, 20),
691 (1448, false, 2069, 3, 20),
692 (1449, true, 2070, 3, 20),
693 (1450, false, 2071, 3, 21),
694 (1451, false, 2072, 3, 20),
695 (1452, false, 2073, 3, 20),
696 (1453, true, 2074, 3, 20),
697 (1454, false, 2075, 3, 21),
698 (1455, false, 2076, 3, 20),
699 (1456, false, 2077, 3, 20),
700 (1457, true, 2078, 3, 20),
701 (1458, false, 2079, 3, 21),
702 (1459, false, 2080, 3, 20),
703 (1460, false, 2081, 3, 20),
704 (1461, true, 2082, 3, 20),
705 (1462, false, 2083, 3, 21),
706 (1463, false, 2084, 3, 20),
707 (1464, false, 2085, 3, 20),
708 (1465, true, 2086, 3, 20),
709 (1466, false, 2087, 3, 21),
710 (1467, false, 2088, 3, 20),
711 (1468, false, 2089, 3, 20),
712 (1469, true, 2090, 3, 20),
713 (1470, false, 2091, 3, 21),
714 (1471, false, 2092, 3, 20),
715 (1472, false, 2093, 3, 20),
716 (1473, false, 2094, 3, 20),
717 (1474, true, 2095, 3, 20),
718 (1475, false, 2096, 3, 20),
719 (1476, false, 2097, 3, 20),
720 (1477, false, 2098, 3, 20),
721 (1478, true, 2099, 3, 20),
722 (1479, false, 2100, 3, 21),
723 (1480, false, 2101, 3, 21),
724 (1481, false, 2102, 3, 21),
725 (1482, true, 2103, 3, 21),
726 (1483, false, 2104, 3, 21),
727 (1484, false, 2105, 3, 21),
728 (1485, false, 2106, 3, 21),
729 (1486, true, 2107, 3, 21),
730 (1487, false, 2108, 3, 21),
731 (1488, false, 2109, 3, 21),
732 (1489, false, 2110, 3, 21),
733 (1490, true, 2111, 3, 21),
734 (1491, false, 2112, 3, 21),
735 (1492, false, 2113, 3, 21),
736 (1493, false, 2114, 3, 21),
737 (1494, true, 2115, 3, 21),
738 (1495, false, 2116, 3, 21),
739 (1496, false, 2117, 3, 21),
740 (1497, false, 2118, 3, 21),
741 (1498, true, 2119, 3, 21),
742 ];
743
744 #[test]
745 fn test_calendar_ut_ac_ir_data() {
746 for &(p_year, leap, iso_year, iso_month, iso_day) in CALENDAR_UT_AC_IR_TEST_DATA.iter() {
747 let persian_date = Date::try_new_persian(p_year, 1, 1).unwrap();
748 assert_eq!(persian_date.is_in_leap_year(), leap);
749 let iso_date = persian_date.to_iso();
750 assert_eq!(iso_date.era_year().year, iso_year);
751 assert_eq!(iso_date.month().ordinal, iso_month);
752 assert_eq!(iso_date.day_of_month().0, iso_day);
753 }
754 }
755}