1use crate::cal::hijri::HijriSimulatedLocation;
8use crate::cal::iso::IsoDateInner;
9use crate::cal::{
10 Buddhist, Chinese, Coptic, Dangi, Ethiopian, EthiopianEraStyle, Gregorian, Hebrew,
11 HijriSimulated, HijriTabular, HijriTabularEpoch, HijriTabularLeapYears, HijriUmmAlQura, Indian,
12 Iso, Japanese, JapaneseExtended, Persian, Roc,
13};
14use crate::error::DateError;
15use crate::types::YearInfo;
16use crate::{types, AsCalendar, Calendar, Date, DateDuration, DateDurationUnit, Ref};
17
18use crate::preferences::{CalendarAlgorithm, HijriCalendarAlgorithm};
19use icu_locale_core::preferences::define_preferences;
20use icu_locale_core::subtags::region;
21use icu_provider::prelude::*;
22
23use core::fmt;
24
25define_preferences!(
26 [Copy]
28 CalendarPreferences,
29 {
30 calendar_algorithm: CalendarAlgorithm
32 }
33);
34
35#[derive(Debug, Clone)]
77#[non_exhaustive]
78pub enum AnyCalendar {
79 Buddhist(Buddhist),
81 Chinese(Chinese),
83 Coptic(Coptic),
85 Dangi(Dangi),
87 Ethiopian(Ethiopian),
89 Gregorian(Gregorian),
91 Hebrew(Hebrew),
93 Indian(Indian),
95 HijriTabular(HijriTabular),
97 HijriSimulated(HijriSimulated),
99 HijriUmmAlQura(HijriUmmAlQura),
101 Iso(Iso),
103 Japanese(Japanese),
105 JapaneseExtended(JapaneseExtended),
107 Persian(Persian),
109 Roc(Roc),
111}
112
113#[derive(Clone, PartialEq, Eq, Debug, Copy)]
116#[non_exhaustive]
117pub enum AnyDateInner {
118 Buddhist(<Buddhist as Calendar>::DateInner),
120 Chinese(<Chinese as Calendar>::DateInner),
122 Coptic(<Coptic as Calendar>::DateInner),
124 Dangi(<Dangi as Calendar>::DateInner),
126 Ethiopian(<Ethiopian as Calendar>::DateInner),
128 Gregorian(<Gregorian as Calendar>::DateInner),
130 Hebrew(<Hebrew as Calendar>::DateInner),
132 Indian(<Indian as Calendar>::DateInner),
134 HijriTabular(
136 <HijriTabular as Calendar>::DateInner,
137 HijriTabularLeapYears,
138 HijriTabularEpoch,
139 ),
140 HijriSimulated(<HijriSimulated as Calendar>::DateInner),
142 HijriUmmAlQura(<HijriUmmAlQura as Calendar>::DateInner),
144 Iso(<Iso as Calendar>::DateInner),
146 Japanese(<Japanese as Calendar>::DateInner),
148 JapaneseExtended(<JapaneseExtended as Calendar>::DateInner),
150 Persian(<Persian as Calendar>::DateInner),
152 Roc(<Roc as Calendar>::DateInner),
154}
155
156macro_rules! match_cal_and_date {
157 (match ($cal:ident, $date:ident): ($cal_matched:ident, $date_matched:ident) => $e:expr) => {
158 match ($cal, $date) {
159 (&Self::Buddhist(ref $cal_matched), &AnyDateInner::Buddhist(ref $date_matched)) => $e,
160 (&Self::Chinese(ref $cal_matched), &AnyDateInner::Chinese(ref $date_matched)) => $e,
161 (&Self::Coptic(ref $cal_matched), &AnyDateInner::Coptic(ref $date_matched)) => $e,
162 (&Self::Dangi(ref $cal_matched), &AnyDateInner::Dangi(ref $date_matched)) => $e,
163 (&Self::Ethiopian(ref $cal_matched), &AnyDateInner::Ethiopian(ref $date_matched)) => $e,
164 (&Self::Gregorian(ref $cal_matched), &AnyDateInner::Gregorian(ref $date_matched)) => $e,
165 (&Self::Hebrew(ref $cal_matched), &AnyDateInner::Hebrew(ref $date_matched)) => $e,
166 (&Self::Indian(ref $cal_matched), &AnyDateInner::Indian(ref $date_matched)) => $e,
167 (
168 &Self::HijriTabular(ref $cal_matched),
169 &AnyDateInner::HijriTabular(ref $date_matched, leap_years, epoch),
170 ) if $cal_matched.epoch == epoch && $cal_matched.leap_years == leap_years => $e,
171 (
172 &Self::HijriSimulated(ref $cal_matched),
173 &AnyDateInner::HijriSimulated(ref $date_matched),
174 ) => $e,
175 (
176 &Self::HijriUmmAlQura(ref $cal_matched),
177 &AnyDateInner::HijriUmmAlQura(ref $date_matched),
178 ) => $e,
179 (&Self::Iso(ref $cal_matched), &AnyDateInner::Iso(ref $date_matched)) => $e,
180 (&Self::Japanese(ref $cal_matched), &AnyDateInner::Japanese(ref $date_matched)) => $e,
181 (
182 &Self::JapaneseExtended(ref $cal_matched),
183 &AnyDateInner::JapaneseExtended(ref $date_matched),
184 ) => $e,
185 (&Self::Persian(ref $cal_matched), &AnyDateInner::Persian(ref $date_matched)) => $e,
186 (&Self::Roc(ref $cal_matched), &AnyDateInner::Roc(ref $date_matched)) => $e,
187 _ => panic!(
188 "Found AnyCalendar with mixed calendar type {:?} and date type {:?}!",
189 $cal.kind().debug_name(),
190 $date.kind().debug_name()
191 ),
192 }
193 };
194}
195
196macro_rules! match_cal {
197 (match $cal:ident: ($cal_matched:ident) => $e:expr) => {
198 match $cal {
199 &Self::Buddhist(ref $cal_matched) => AnyDateInner::Buddhist($e),
200 &Self::Chinese(ref $cal_matched) => AnyDateInner::Chinese($e),
201 &Self::Coptic(ref $cal_matched) => AnyDateInner::Coptic($e),
202 &Self::Dangi(ref $cal_matched) => AnyDateInner::Dangi($e),
203 &Self::Ethiopian(ref $cal_matched) => AnyDateInner::Ethiopian($e),
204 &Self::Gregorian(ref $cal_matched) => AnyDateInner::Gregorian($e),
205 &Self::Hebrew(ref $cal_matched) => AnyDateInner::Hebrew($e),
206 &Self::Indian(ref $cal_matched) => AnyDateInner::Indian($e),
207 &Self::HijriSimulated(ref $cal_matched) => AnyDateInner::HijriSimulated($e),
208 &Self::HijriTabular(ref $cal_matched) => {
209 AnyDateInner::HijriTabular($e, $cal_matched.leap_years, $cal_matched.epoch)
210 }
211 &Self::HijriUmmAlQura(ref $cal_matched) => AnyDateInner::HijriUmmAlQura($e),
212 &Self::Iso(ref $cal_matched) => AnyDateInner::Iso($e),
213 &Self::Japanese(ref $cal_matched) => AnyDateInner::Japanese($e),
214 &Self::JapaneseExtended(ref $cal_matched) => AnyDateInner::JapaneseExtended($e),
215 &Self::Persian(ref $cal_matched) => AnyDateInner::Persian($e),
216 &Self::Roc(ref $cal_matched) => AnyDateInner::Roc($e),
217 }
218 };
219}
220
221impl crate::cal::scaffold::UnstableSealed for AnyCalendar {}
222impl Calendar for AnyCalendar {
223 type DateInner = AnyDateInner;
224 type Year = YearInfo;
225
226 fn from_codes(
227 &self,
228 era: Option<&str>,
229 year: i32,
230 month_code: types::MonthCode,
231 day: u8,
232 ) -> Result<Self::DateInner, DateError> {
233 Ok(match_cal!(match self: (c) => c.from_codes(era, year, month_code, day)?))
234 }
235
236 fn from_iso(&self, iso: IsoDateInner) -> AnyDateInner {
237 match_cal!(match self: (c) => c.from_iso(iso))
238 }
239
240 fn from_rata_die(&self, rd: calendrical_calculations::rata_die::RataDie) -> Self::DateInner {
241 match_cal!(match self: (c) => c.from_rata_die(rd))
242 }
243
244 fn to_rata_die(&self, date: &Self::DateInner) -> calendrical_calculations::rata_die::RataDie {
245 match_cal_and_date!(match (self, date): (c, d) => c.to_rata_die(d))
246 }
247
248 fn to_iso(&self, date: &Self::DateInner) -> IsoDateInner {
249 match_cal_and_date!(match (self, date): (c, d) => c.to_iso(d))
250 }
251
252 fn months_in_year(&self, date: &Self::DateInner) -> u8 {
253 match_cal_and_date!(match (self, date): (c, d) => c.months_in_year(d))
254 }
255
256 fn days_in_year(&self, date: &Self::DateInner) -> u16 {
257 match_cal_and_date!(match (self, date): (c, d) => c.days_in_year(d))
258 }
259
260 fn days_in_month(&self, date: &Self::DateInner) -> u8 {
261 match_cal_and_date!(match (self, date): (c, d) => c.days_in_month(d))
262 }
263
264 fn offset_date(&self, date: &mut Self::DateInner, offset: DateDuration<Self>) {
265 match (self, date) {
266 (Self::Buddhist(c), AnyDateInner::Buddhist(ref mut d)) => {
267 c.offset_date(d, offset.cast_unit())
268 }
269 (Self::Chinese(c), AnyDateInner::Chinese(ref mut d)) => {
270 c.offset_date(d, offset.cast_unit())
271 }
272 (Self::Coptic(c), AnyDateInner::Coptic(ref mut d)) => {
273 c.offset_date(d, offset.cast_unit())
274 }
275 (Self::Dangi(c), AnyDateInner::Dangi(ref mut d)) => {
276 c.offset_date(d, offset.cast_unit())
277 }
278 (Self::Ethiopian(c), AnyDateInner::Ethiopian(ref mut d)) => {
279 c.offset_date(d, offset.cast_unit())
280 }
281 (Self::Gregorian(c), AnyDateInner::Gregorian(ref mut d)) => {
282 c.offset_date(d, offset.cast_unit())
283 }
284 (Self::Hebrew(c), AnyDateInner::Hebrew(ref mut d)) => {
285 c.offset_date(d, offset.cast_unit())
286 }
287 (Self::Indian(c), AnyDateInner::Indian(ref mut d)) => {
288 c.offset_date(d, offset.cast_unit())
289 }
290 (
291 Self::HijriTabular(c),
292 &mut AnyDateInner::HijriTabular(ref mut d, leap_years, epoch),
293 ) if c.epoch == epoch && c.leap_years == leap_years => {
294 c.offset_date(d, offset.cast_unit())
295 }
296 (Self::HijriSimulated(c), AnyDateInner::HijriSimulated(ref mut d)) => {
297 c.offset_date(d, offset.cast_unit())
298 }
299 (Self::HijriUmmAlQura(c), AnyDateInner::HijriUmmAlQura(ref mut d)) => {
300 c.offset_date(d, offset.cast_unit())
301 }
302 (Self::Iso(c), AnyDateInner::Iso(ref mut d)) => c.offset_date(d, offset.cast_unit()),
303 (Self::Japanese(c), AnyDateInner::Japanese(ref mut d)) => {
304 c.offset_date(d, offset.cast_unit())
305 }
306 (Self::JapaneseExtended(c), AnyDateInner::JapaneseExtended(ref mut d)) => {
307 c.offset_date(d, offset.cast_unit())
308 }
309 (Self::Persian(c), AnyDateInner::Persian(ref mut d)) => {
310 c.offset_date(d, offset.cast_unit())
311 }
312 (Self::Roc(c), AnyDateInner::Roc(ref mut d)) => c.offset_date(d, offset.cast_unit()),
313 #[allow(clippy::panic)]
315 (_, d) => panic!(
316 "Found AnyCalendar with mixed calendar type {} and date type {}!",
317 self.kind().debug_name(),
318 d.kind().debug_name()
319 ),
320 }
321 }
322
323 fn until(
324 &self,
325 date1: &Self::DateInner,
326 date2: &Self::DateInner,
327 calendar2: &Self,
328 largest_unit: DateDurationUnit,
329 smallest_unit: DateDurationUnit,
330 ) -> DateDuration<Self> {
331 match (self, calendar2, date1, date2) {
332 (
333 Self::Buddhist(c1),
334 Self::Buddhist(c2),
335 AnyDateInner::Buddhist(d1),
336 AnyDateInner::Buddhist(d2),
337 ) => c1
338 .until(d1, d2, c2, largest_unit, smallest_unit)
339 .cast_unit(),
340 (
341 Self::Chinese(c1),
342 Self::Chinese(c2),
343 AnyDateInner::Chinese(d1),
344 AnyDateInner::Chinese(d2),
345 ) => c1
346 .until(d1, d2, c2, largest_unit, smallest_unit)
347 .cast_unit(),
348 (
349 Self::Coptic(c1),
350 Self::Coptic(c2),
351 AnyDateInner::Coptic(d1),
352 AnyDateInner::Coptic(d2),
353 ) => c1
354 .until(d1, d2, c2, largest_unit, smallest_unit)
355 .cast_unit(),
356 (
357 Self::Dangi(c1),
358 Self::Dangi(c2),
359 AnyDateInner::Dangi(d1),
360 AnyDateInner::Dangi(d2),
361 ) => c1
362 .until(d1, d2, c2, largest_unit, smallest_unit)
363 .cast_unit(),
364 (
365 Self::Ethiopian(c1),
366 Self::Ethiopian(c2),
367 AnyDateInner::Ethiopian(d1),
368 AnyDateInner::Ethiopian(d2),
369 ) => c1
370 .until(d1, d2, c2, largest_unit, smallest_unit)
371 .cast_unit(),
372 (
373 Self::Gregorian(c1),
374 Self::Gregorian(c2),
375 AnyDateInner::Gregorian(d1),
376 AnyDateInner::Gregorian(d2),
377 ) => c1
378 .until(d1, d2, c2, largest_unit, smallest_unit)
379 .cast_unit(),
380 (
381 Self::Hebrew(c1),
382 Self::Hebrew(c2),
383 AnyDateInner::Hebrew(d1),
384 AnyDateInner::Hebrew(d2),
385 ) => c1
386 .until(d1, d2, c2, largest_unit, smallest_unit)
387 .cast_unit(),
388 (
389 Self::Indian(c1),
390 Self::Indian(c2),
391 AnyDateInner::Indian(d1),
392 AnyDateInner::Indian(d2),
393 ) => c1
394 .until(d1, d2, c2, largest_unit, smallest_unit)
395 .cast_unit(),
396 (
397 Self::HijriTabular(c1),
398 Self::HijriTabular(c2),
399 &AnyDateInner::HijriTabular(ref d1, l1, e1),
400 &AnyDateInner::HijriTabular(ref d2, l2, e2),
401 ) if c1.epoch == c2.epoch
402 && c2.epoch == e1
403 && e1 == e2
404 && c1.leap_years == c2.leap_years
405 && c2.leap_years == l1
406 && l1 == l2 =>
407 {
408 c1.until(d1, d2, c2, largest_unit, smallest_unit)
409 .cast_unit()
410 }
411 (
412 Self::HijriSimulated(c1),
413 Self::HijriSimulated(c2),
414 AnyDateInner::HijriSimulated(d1),
415 AnyDateInner::HijriSimulated(d2),
416 ) => c1
417 .until(d1, d2, c2, largest_unit, smallest_unit)
418 .cast_unit(),
419 (
420 Self::HijriUmmAlQura(c1),
421 Self::HijriUmmAlQura(c2),
422 AnyDateInner::HijriUmmAlQura(d1),
423 AnyDateInner::HijriUmmAlQura(d2),
424 ) => c1
425 .until(d1, d2, c2, largest_unit, smallest_unit)
426 .cast_unit(),
427 (Self::Iso(c1), Self::Iso(c2), AnyDateInner::Iso(d1), AnyDateInner::Iso(d2)) => c1
428 .until(d1, d2, c2, largest_unit, smallest_unit)
429 .cast_unit(),
430 (
431 Self::Japanese(c1),
432 Self::Japanese(c2),
433 AnyDateInner::Japanese(d1),
434 AnyDateInner::Japanese(d2),
435 ) => c1
436 .until(d1, d2, c2, largest_unit, smallest_unit)
437 .cast_unit(),
438 (
439 Self::JapaneseExtended(c1),
440 Self::JapaneseExtended(c2),
441 AnyDateInner::JapaneseExtended(d1),
442 AnyDateInner::JapaneseExtended(d2),
443 ) => c1
444 .until(d1, d2, c2, largest_unit, smallest_unit)
445 .cast_unit(),
446 (
447 Self::Persian(c1),
448 Self::Persian(c2),
449 AnyDateInner::Persian(d1),
450 AnyDateInner::Persian(d2),
451 ) => c1
452 .until(d1, d2, c2, largest_unit, smallest_unit)
453 .cast_unit(),
454 (Self::Roc(c1), Self::Roc(c2), AnyDateInner::Roc(d1), AnyDateInner::Roc(d2)) => c1
455 .until(d1, d2, c2, largest_unit, smallest_unit)
456 .cast_unit(),
457 _ => {
458 let iso = calendar2.to_iso(date2);
460
461 match_cal_and_date!(match (self, date1):
462 (c1, d1) => {
463 let d2 = c1.from_iso(iso);
464 let until = c1.until(d1, &d2, c1, largest_unit, smallest_unit);
465 until.cast_unit::<AnyCalendar>()
466 }
467 )
468 }
469 }
470 }
471
472 fn year_info(&self, date: &Self::DateInner) -> types::YearInfo {
473 match_cal_and_date!(match (self, date): (c, d) => c.year_info(d).into())
474 }
475
476 fn extended_year(&self, date: &Self::DateInner) -> i32 {
477 match_cal_and_date!(match (self, date): (c, d) => c.extended_year(d))
478 }
479
480 fn is_in_leap_year(&self, date: &Self::DateInner) -> bool {
482 match_cal_and_date!(match (self, date): (c, d) => c.is_in_leap_year(d))
483 }
484
485 fn month(&self, date: &Self::DateInner) -> types::MonthInfo {
487 match_cal_and_date!(match (self, date): (c, d) => c.month(d))
488 }
489
490 fn day_of_month(&self, date: &Self::DateInner) -> types::DayOfMonth {
492 match_cal_and_date!(match (self, date): (c, d) => c.day_of_month(d))
493 }
494
495 fn day_of_year(&self, date: &Self::DateInner) -> types::DayOfYear {
497 match_cal_and_date!(match (self, date): (c, d) => c.day_of_year(d))
498 }
499
500 fn debug_name(&self) -> &'static str {
501 match self.kind() {
502 AnyCalendarKind::Buddhist => "AnyCalendar (Buddhist)",
503 AnyCalendarKind::Chinese => "AnyCalendar (Chinese)",
504 AnyCalendarKind::Coptic => "AnyCalendar (Coptic)",
505 AnyCalendarKind::Dangi => "AnyCalendar (Dangi)",
506 AnyCalendarKind::Ethiopian => "AnyCalendar (Ethiopian, Amete Miret)",
507 AnyCalendarKind::EthiopianAmeteAlem => "AnyCalendar (Ethiopian, Amete Alem)",
508 AnyCalendarKind::Gregorian => "AnyCalendar (Gregorian)",
509 AnyCalendarKind::Hebrew => "AnyCalendar (Hebrew)",
510 AnyCalendarKind::Indian => "AnyCalendar (Indian)",
511 AnyCalendarKind::HijriTabularTypeIIFriday => {
512 "AnyCalendar (Hijri, tabular, type II leap years, Friday epoch)"
513 }
514 AnyCalendarKind::HijriTabularTypeIIThursday => {
515 "AnyCalendar (Hijri, tabular, type II leap years, Thursday epoch)"
516 }
517 AnyCalendarKind::HijriSimulatedMecca => "AnyCalendar (Hijri, simulated Mecca)",
518 AnyCalendarKind::HijriUmmAlQura => "AnyCalendar (Hijri, Umm al-Qura)",
519 AnyCalendarKind::Iso => "AnyCalendar (Iso)",
520 AnyCalendarKind::Japanese => "AnyCalendar (Japanese)",
521 AnyCalendarKind::JapaneseExtended => "AnyCalendar (Japanese, historical era data)",
522 AnyCalendarKind::Persian => "AnyCalendar (Persian)",
523 AnyCalendarKind::Roc => "AnyCalendar (Roc)",
524 }
525 }
526
527 fn calendar_algorithm(&self) -> Option<CalendarAlgorithm> {
528 match self {
529 Self::Buddhist(ref c) => c.calendar_algorithm(),
530 Self::Chinese(ref c) => c.calendar_algorithm(),
531 Self::Coptic(ref c) => c.calendar_algorithm(),
532 Self::Dangi(ref c) => c.calendar_algorithm(),
533 Self::Ethiopian(ref c) => c.calendar_algorithm(),
534 Self::Gregorian(ref c) => c.calendar_algorithm(),
535 Self::Hebrew(ref c) => c.calendar_algorithm(),
536 Self::Indian(ref c) => c.calendar_algorithm(),
537 Self::HijriSimulated(ref c) => c.calendar_algorithm(),
538 Self::HijriTabular(ref c) => c.calendar_algorithm(),
539 Self::HijriUmmAlQura(ref c) => c.calendar_algorithm(),
540 Self::Iso(ref c) => c.calendar_algorithm(),
541 Self::Japanese(ref c) => c.calendar_algorithm(),
542 Self::JapaneseExtended(ref c) => c.calendar_algorithm(),
543 Self::Persian(ref c) => c.calendar_algorithm(),
544 Self::Roc(ref c) => c.calendar_algorithm(),
545 }
546 }
547}
548
549impl AnyCalendar {
550 #[cfg(feature = "compiled_data")]
556 pub const fn new(kind: AnyCalendarKind) -> Self {
557 match kind {
558 AnyCalendarKind::Buddhist => AnyCalendar::Buddhist(Buddhist),
559 AnyCalendarKind::Chinese => AnyCalendar::Chinese(Chinese::new()),
560 AnyCalendarKind::Coptic => AnyCalendar::Coptic(Coptic),
561 AnyCalendarKind::Dangi => AnyCalendar::Dangi(Dangi::new()),
562 AnyCalendarKind::Ethiopian => AnyCalendar::Ethiopian(Ethiopian::new_with_era_style(
563 EthiopianEraStyle::AmeteMihret,
564 )),
565 AnyCalendarKind::EthiopianAmeteAlem => {
566 AnyCalendar::Ethiopian(Ethiopian::new_with_era_style(EthiopianEraStyle::AmeteAlem))
567 }
568 AnyCalendarKind::Gregorian => AnyCalendar::Gregorian(Gregorian),
569 AnyCalendarKind::Hebrew => AnyCalendar::Hebrew(Hebrew),
570 AnyCalendarKind::Indian => AnyCalendar::Indian(Indian),
571 AnyCalendarKind::HijriTabularTypeIIFriday => {
572 AnyCalendar::HijriTabular(HijriTabular::new(
573 crate::cal::hijri::HijriTabularLeapYears::TypeII,
574 HijriTabularEpoch::Friday,
575 ))
576 }
577 AnyCalendarKind::HijriSimulatedMecca => {
578 AnyCalendar::HijriSimulated(HijriSimulated::new_mecca())
579 }
580 AnyCalendarKind::HijriTabularTypeIIThursday => {
581 AnyCalendar::HijriTabular(HijriTabular::new(
582 crate::cal::hijri::HijriTabularLeapYears::TypeII,
583 HijriTabularEpoch::Thursday,
584 ))
585 }
586 AnyCalendarKind::HijriUmmAlQura => AnyCalendar::HijriUmmAlQura(HijriUmmAlQura::new()),
587 AnyCalendarKind::Iso => AnyCalendar::Iso(Iso),
588 AnyCalendarKind::Japanese => AnyCalendar::Japanese(Japanese::new()),
589 AnyCalendarKind::JapaneseExtended => {
590 AnyCalendar::JapaneseExtended(JapaneseExtended::new())
591 }
592 AnyCalendarKind::Persian => AnyCalendar::Persian(Persian),
593 AnyCalendarKind::Roc => AnyCalendar::Roc(Roc),
594 }
595 }
596
597 #[cfg(feature = "serde")]
598 #[doc = icu_provider::gen_buffer_unstable_docs!(BUFFER, Self::new)]
599 pub fn try_new_with_buffer_provider<P>(
600 provider: &P,
601 kind: AnyCalendarKind,
602 ) -> Result<Self, DataError>
603 where
604 P: BufferProvider + ?Sized,
605 {
606 Ok(match kind {
607 AnyCalendarKind::Buddhist => AnyCalendar::Buddhist(Buddhist),
608 AnyCalendarKind::Chinese => {
609 AnyCalendar::Chinese(Chinese::try_new_with_buffer_provider(provider)?)
610 }
611 AnyCalendarKind::Coptic => AnyCalendar::Coptic(Coptic),
612 AnyCalendarKind::Dangi => {
613 AnyCalendar::Dangi(Dangi::try_new_with_buffer_provider(provider)?)
614 }
615 AnyCalendarKind::Ethiopian => AnyCalendar::Ethiopian(Ethiopian::new_with_era_style(
616 EthiopianEraStyle::AmeteMihret,
617 )),
618 AnyCalendarKind::EthiopianAmeteAlem => {
619 AnyCalendar::Ethiopian(Ethiopian::new_with_era_style(EthiopianEraStyle::AmeteAlem))
620 }
621 AnyCalendarKind::Gregorian => AnyCalendar::Gregorian(Gregorian),
622 AnyCalendarKind::Hebrew => AnyCalendar::Hebrew(Hebrew),
623 AnyCalendarKind::Indian => AnyCalendar::Indian(Indian),
624 AnyCalendarKind::HijriTabularTypeIIFriday => {
625 AnyCalendar::HijriTabular(HijriTabular::new(
626 crate::cal::hijri::HijriTabularLeapYears::TypeII,
627 HijriTabularEpoch::Friday,
628 ))
629 }
630 AnyCalendarKind::HijriSimulatedMecca => AnyCalendar::HijriSimulated(
631 HijriSimulated::try_new_mecca_with_buffer_provider(provider)?,
632 ),
633 AnyCalendarKind::HijriTabularTypeIIThursday => {
634 AnyCalendar::HijriTabular(HijriTabular::new(
635 crate::cal::hijri::HijriTabularLeapYears::TypeII,
636 HijriTabularEpoch::Thursday,
637 ))
638 }
639 AnyCalendarKind::HijriUmmAlQura => AnyCalendar::HijriUmmAlQura(HijriUmmAlQura::new()),
640 AnyCalendarKind::Iso => AnyCalendar::Iso(Iso),
641 AnyCalendarKind::Japanese => {
642 AnyCalendar::Japanese(Japanese::try_new_with_buffer_provider(provider)?)
643 }
644 AnyCalendarKind::JapaneseExtended => AnyCalendar::JapaneseExtended(
645 JapaneseExtended::try_new_with_buffer_provider(provider)?,
646 ),
647 AnyCalendarKind::Persian => AnyCalendar::Persian(Persian),
648 AnyCalendarKind::Roc => AnyCalendar::Roc(Roc),
649 })
650 }
651
652 #[doc = icu_provider::gen_buffer_unstable_docs!(UNSTABLE, Self::new)]
653 pub fn try_new_unstable<P>(provider: &P, kind: AnyCalendarKind) -> Result<Self, DataError>
654 where
655 P: DataProvider<crate::provider::CalendarJapaneseModernV1>
656 + DataProvider<crate::provider::CalendarJapaneseExtendedV1>
657 + DataProvider<crate::provider::CalendarChineseV1>
658 + DataProvider<crate::provider::CalendarDangiV1>
659 + DataProvider<crate::provider::CalendarHijriSimulatedMeccaV1>
660 + ?Sized,
661 {
662 Ok(match kind {
663 AnyCalendarKind::Buddhist => AnyCalendar::Buddhist(Buddhist),
664 AnyCalendarKind::Chinese => AnyCalendar::Chinese(Chinese::try_new_unstable(provider)?),
665 AnyCalendarKind::Coptic => AnyCalendar::Coptic(Coptic),
666 AnyCalendarKind::Dangi => AnyCalendar::Dangi(Dangi::try_new_unstable(provider)?),
667 AnyCalendarKind::Ethiopian => AnyCalendar::Ethiopian(Ethiopian::new_with_era_style(
668 EthiopianEraStyle::AmeteMihret,
669 )),
670 AnyCalendarKind::EthiopianAmeteAlem => {
671 AnyCalendar::Ethiopian(Ethiopian::new_with_era_style(EthiopianEraStyle::AmeteAlem))
672 }
673 AnyCalendarKind::Gregorian => AnyCalendar::Gregorian(Gregorian),
674 AnyCalendarKind::Hebrew => AnyCalendar::Hebrew(Hebrew),
675 AnyCalendarKind::Indian => AnyCalendar::Indian(Indian),
676 AnyCalendarKind::HijriTabularTypeIIFriday => {
677 AnyCalendar::HijriTabular(HijriTabular::new(
678 crate::cal::hijri::HijriTabularLeapYears::TypeII,
679 HijriTabularEpoch::Friday,
680 ))
681 }
682 AnyCalendarKind::HijriSimulatedMecca => {
683 AnyCalendar::HijriSimulated(HijriSimulated::try_new_mecca_unstable(provider)?)
684 }
685 AnyCalendarKind::HijriTabularTypeIIThursday => {
686 AnyCalendar::HijriTabular(HijriTabular::new(
687 crate::cal::hijri::HijriTabularLeapYears::TypeII,
688 HijriTabularEpoch::Thursday,
689 ))
690 }
691 AnyCalendarKind::HijriUmmAlQura => AnyCalendar::HijriUmmAlQura(HijriUmmAlQura::new()),
692 AnyCalendarKind::Iso => AnyCalendar::Iso(Iso),
693 AnyCalendarKind::Japanese => {
694 AnyCalendar::Japanese(Japanese::try_new_unstable(provider)?)
695 }
696 AnyCalendarKind::JapaneseExtended => {
697 AnyCalendar::JapaneseExtended(JapaneseExtended::try_new_unstable(provider)?)
698 }
699 AnyCalendarKind::Persian => AnyCalendar::Persian(Persian),
700 AnyCalendarKind::Roc => AnyCalendar::Roc(Roc),
701 })
702 }
703
704 pub fn kind(&self) -> AnyCalendarKind {
706 match *self {
707 Self::Buddhist(_) => AnyCalendarKind::Buddhist,
708 Self::Chinese(_) => AnyCalendarKind::Chinese,
709 Self::Coptic(_) => AnyCalendarKind::Coptic,
710 Self::Dangi(_) => AnyCalendarKind::Dangi,
711 Self::Ethiopian(ref e) => IntoAnyCalendar::kind(e),
712 Self::Gregorian(_) => AnyCalendarKind::Gregorian,
713 Self::Hebrew(_) => AnyCalendarKind::Hebrew,
714 Self::Indian(_) => AnyCalendarKind::Indian,
715 Self::HijriTabular(ref h) => IntoAnyCalendar::kind(h),
716 Self::HijriSimulated(ref h) => IntoAnyCalendar::kind(h),
717 Self::HijriUmmAlQura(_) => AnyCalendarKind::HijriUmmAlQura,
718 Self::Iso(_) => AnyCalendarKind::Iso,
719 Self::Japanese(_) => AnyCalendarKind::Japanese,
720 Self::JapaneseExtended(_) => AnyCalendarKind::JapaneseExtended,
721 Self::Persian(_) => AnyCalendarKind::Persian,
722 Self::Roc(_) => AnyCalendarKind::Roc,
723 }
724 }
725}
726
727impl<C: AsCalendar<Calendar = AnyCalendar>> Date<C> {
728 pub fn convert_any<'a>(&self, calendar: &'a AnyCalendar) -> Date<Ref<'a, AnyCalendar>> {
730 if calendar.kind() != self.calendar.as_calendar().kind() {
731 Date::new_from_iso(self.to_iso(), Ref(calendar))
732 } else {
733 Date {
734 inner: self.inner,
735 calendar: Ref(calendar),
736 }
737 }
738 }
739}
740
741impl AnyDateInner {
742 fn kind(&self) -> AnyCalendarKind {
743 match *self {
744 AnyDateInner::Buddhist(_) => AnyCalendarKind::Buddhist,
745 AnyDateInner::Chinese(_) => AnyCalendarKind::Chinese,
746 AnyDateInner::Coptic(_) => AnyCalendarKind::Coptic,
747 AnyDateInner::Dangi(_) => AnyCalendarKind::Dangi,
748 AnyDateInner::Ethiopian(_) => AnyCalendarKind::Ethiopian,
749 AnyDateInner::Gregorian(_) => AnyCalendarKind::Gregorian,
750 AnyDateInner::Hebrew(_) => AnyCalendarKind::Hebrew,
751 AnyDateInner::Indian(_) => AnyCalendarKind::Indian,
752 AnyDateInner::HijriTabular(
753 _,
754 HijriTabularLeapYears::TypeII,
755 HijriTabularEpoch::Friday,
756 ) => AnyCalendarKind::HijriTabularTypeIIFriday,
757 AnyDateInner::HijriSimulated(_) => AnyCalendarKind::HijriSimulatedMecca,
758 AnyDateInner::HijriTabular(
759 _,
760 HijriTabularLeapYears::TypeII,
761 HijriTabularEpoch::Thursday,
762 ) => AnyCalendarKind::HijriTabularTypeIIThursday,
763 AnyDateInner::HijriUmmAlQura(_) => AnyCalendarKind::HijriUmmAlQura,
764 AnyDateInner::Iso(_) => AnyCalendarKind::Iso,
765 AnyDateInner::Japanese(_) => AnyCalendarKind::Japanese,
766 AnyDateInner::JapaneseExtended(_) => AnyCalendarKind::JapaneseExtended,
767 AnyDateInner::Persian(_) => AnyCalendarKind::Persian,
768 AnyDateInner::Roc(_) => AnyCalendarKind::Roc,
769 }
770 }
771}
772
773#[non_exhaustive]
775#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
776pub enum AnyCalendarKind {
777 Buddhist,
779 Chinese,
781 Coptic,
783 Dangi,
785 Ethiopian,
787 EthiopianAmeteAlem,
789 Gregorian,
791 Hebrew,
793 Indian,
795 HijriTabularTypeIIFriday,
797 HijriSimulatedMecca,
799 HijriTabularTypeIIThursday,
801 HijriUmmAlQura,
803 Iso,
805 Japanese,
807 JapaneseExtended,
809 Persian,
811 Roc,
813}
814
815impl AnyCalendarKind {
816 pub fn new(prefs: CalendarPreferences) -> Self {
818 let algo = prefs.calendar_algorithm;
819 let region = prefs.locale_preferences.region();
820 if let Some(kind) = algo.and_then(|a| a.try_into().ok()) {
821 return kind;
822 }
823 if region == Some(region!("TH")) {
824 AnyCalendarKind::Buddhist
825 } else if region == Some(region!("AF")) || region == Some(region!("IR")) {
826 AnyCalendarKind::Persian
827 } else if region == Some(region!("SA")) && algo == Some(CalendarAlgorithm::Hijri(None)) {
828 AnyCalendarKind::HijriSimulatedMecca
829 } else {
830 AnyCalendarKind::Gregorian
831 }
832 }
833
834 fn debug_name(self) -> &'static str {
835 match self {
836 AnyCalendarKind::Buddhist => Buddhist.debug_name(),
837 AnyCalendarKind::Chinese => Chinese::DEBUG_NAME,
838 AnyCalendarKind::Coptic => Coptic.debug_name(),
839 AnyCalendarKind::Dangi => Dangi::DEBUG_NAME,
840 AnyCalendarKind::Ethiopian => Ethiopian(false).debug_name(),
841 AnyCalendarKind::EthiopianAmeteAlem => Ethiopian(true).debug_name(),
842 AnyCalendarKind::Gregorian => Gregorian.debug_name(),
843 AnyCalendarKind::Hebrew => Hebrew.debug_name(),
844 AnyCalendarKind::Indian => Indian.debug_name(),
845 AnyCalendarKind::HijriTabularTypeIIFriday => HijriTabular::new(
846 crate::cal::hijri::HijriTabularLeapYears::TypeII,
847 HijriTabularEpoch::Friday,
848 )
849 .debug_name(),
850 AnyCalendarKind::HijriSimulatedMecca => HijriSimulated::DEBUG_NAME,
851 AnyCalendarKind::HijriTabularTypeIIThursday => HijriTabular::new(
852 crate::cal::hijri::HijriTabularLeapYears::TypeII,
853 HijriTabularEpoch::Thursday,
854 )
855 .debug_name(),
856 AnyCalendarKind::HijriUmmAlQura => HijriUmmAlQura::DEBUG_NAME,
857 AnyCalendarKind::Iso => Iso.debug_name(),
858 AnyCalendarKind::Japanese => Japanese::DEBUG_NAME,
859 AnyCalendarKind::JapaneseExtended => JapaneseExtended::DEBUG_NAME,
860 AnyCalendarKind::Persian => Persian.debug_name(),
861 AnyCalendarKind::Roc => Roc.debug_name(),
862 }
863 }
864}
865
866impl TryFrom<CalendarAlgorithm> for AnyCalendarKind {
867 type Error = ();
868 fn try_from(v: CalendarAlgorithm) -> Result<Self, Self::Error> {
869 use CalendarAlgorithm::*;
870 match v {
871 Buddhist => Ok(AnyCalendarKind::Buddhist),
872 Chinese => Ok(AnyCalendarKind::Chinese),
873 Coptic => Ok(AnyCalendarKind::Coptic),
874 Dangi => Ok(AnyCalendarKind::Dangi),
875 Ethioaa => Ok(AnyCalendarKind::EthiopianAmeteAlem),
876 Ethiopic => Ok(AnyCalendarKind::Ethiopian),
877 Gregory => Ok(AnyCalendarKind::Gregorian),
878 Hebrew => Ok(AnyCalendarKind::Hebrew),
879 Indian => Ok(AnyCalendarKind::Indian),
880 Hijri(None) => Err(()),
881 Hijri(Some(HijriCalendarAlgorithm::Umalqura)) => Ok(AnyCalendarKind::HijriUmmAlQura),
882 Hijri(Some(HijriCalendarAlgorithm::Tbla)) => {
883 Ok(AnyCalendarKind::HijriTabularTypeIIThursday)
884 }
885 Hijri(Some(HijriCalendarAlgorithm::Civil)) => {
886 Ok(AnyCalendarKind::HijriTabularTypeIIFriday)
887 }
888 Hijri(Some(HijriCalendarAlgorithm::Rgsa)) => Ok(AnyCalendarKind::HijriSimulatedMecca),
889 Iso8601 => Ok(AnyCalendarKind::Iso),
890 Japanese => Ok(AnyCalendarKind::Japanese),
891 Persian => Ok(AnyCalendarKind::Persian),
892 Roc => Ok(AnyCalendarKind::Roc),
893 _ => {
894 debug_assert!(false, "unknown calendar algorithm {v:?}");
895 Err(())
896 }
897 }
898 }
899}
900
901impl fmt::Display for AnyCalendarKind {
902 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
903 fmt::Debug::fmt(self, f)
904 }
905}
906
907pub trait IntoAnyCalendar: Calendar + Sized {
909 fn to_any(self) -> AnyCalendar;
913
914 fn kind(&self) -> AnyCalendarKind;
916
917 fn from_any(any: AnyCalendar) -> Result<Self, AnyCalendar>;
922
923 fn from_any_ref(any: &AnyCalendar) -> Option<&Self>;
927
928 fn date_to_any(&self, d: &Self::DateInner) -> AnyDateInner;
932}
933
934impl IntoAnyCalendar for AnyCalendar {
935 #[inline]
936 fn to_any(self) -> AnyCalendar {
937 self
938 }
939 #[inline]
940 fn kind(&self) -> AnyCalendarKind {
941 self.kind()
942 }
943 #[inline]
944 fn from_any(any: AnyCalendar) -> Result<Self, AnyCalendar> {
945 Ok(any)
946 }
947 #[inline]
948 fn from_any_ref(any: &AnyCalendar) -> Option<&Self> {
949 Some(any)
950 }
951 #[inline]
952 fn date_to_any(&self, d: &Self::DateInner) -> AnyDateInner {
953 *d
954 }
955}
956
957impl IntoAnyCalendar for Buddhist {
958 #[inline]
959 fn to_any(self) -> AnyCalendar {
960 AnyCalendar::Buddhist(Buddhist)
961 }
962 #[inline]
963 fn kind(&self) -> AnyCalendarKind {
964 AnyCalendarKind::Buddhist
965 }
966 #[inline]
967 fn from_any(any: AnyCalendar) -> Result<Self, AnyCalendar> {
968 if let AnyCalendar::Buddhist(cal) = any {
969 Ok(cal)
970 } else {
971 Err(any)
972 }
973 }
974 #[inline]
975 fn from_any_ref(any: &AnyCalendar) -> Option<&Self> {
976 if let AnyCalendar::Buddhist(cal) = any {
977 Some(cal)
978 } else {
979 None
980 }
981 }
982 #[inline]
983 fn date_to_any(&self, d: &Self::DateInner) -> AnyDateInner {
984 AnyDateInner::Buddhist(*d)
985 }
986}
987
988impl From<Buddhist> for AnyCalendar {
989 fn from(value: Buddhist) -> AnyCalendar {
990 value.to_any()
991 }
992}
993
994impl IntoAnyCalendar for Chinese {
995 #[inline]
996 fn to_any(self) -> AnyCalendar {
997 AnyCalendar::Chinese(self)
998 }
999 #[inline]
1000 fn kind(&self) -> AnyCalendarKind {
1001 AnyCalendarKind::Chinese
1002 }
1003 #[inline]
1004 fn from_any(any: AnyCalendar) -> Result<Self, AnyCalendar> {
1005 if let AnyCalendar::Chinese(cal) = any {
1006 Ok(cal)
1007 } else {
1008 Err(any)
1009 }
1010 }
1011 #[inline]
1012 fn from_any_ref(any: &AnyCalendar) -> Option<&Self> {
1013 if let AnyCalendar::Chinese(cal) = any {
1014 Some(cal)
1015 } else {
1016 None
1017 }
1018 }
1019 #[inline]
1020 fn date_to_any(&self, d: &Self::DateInner) -> AnyDateInner {
1021 AnyDateInner::Chinese(*d)
1022 }
1023}
1024
1025impl From<Chinese> for AnyCalendar {
1026 fn from(value: Chinese) -> AnyCalendar {
1027 value.to_any()
1028 }
1029}
1030
1031impl IntoAnyCalendar for Coptic {
1032 #[inline]
1033 fn to_any(self) -> AnyCalendar {
1034 AnyCalendar::Coptic(Coptic)
1035 }
1036 #[inline]
1037 fn kind(&self) -> AnyCalendarKind {
1038 AnyCalendarKind::Coptic
1039 }
1040 #[inline]
1041 fn from_any(any: AnyCalendar) -> Result<Self, AnyCalendar> {
1042 if let AnyCalendar::Coptic(cal) = any {
1043 Ok(cal)
1044 } else {
1045 Err(any)
1046 }
1047 }
1048 #[inline]
1049 fn from_any_ref(any: &AnyCalendar) -> Option<&Self> {
1050 if let AnyCalendar::Coptic(cal) = any {
1051 Some(cal)
1052 } else {
1053 None
1054 }
1055 }
1056 #[inline]
1057 fn date_to_any(&self, d: &Self::DateInner) -> AnyDateInner {
1058 AnyDateInner::Coptic(*d)
1059 }
1060}
1061
1062impl From<Coptic> for AnyCalendar {
1063 fn from(value: Coptic) -> AnyCalendar {
1064 value.to_any()
1065 }
1066}
1067
1068impl IntoAnyCalendar for Dangi {
1069 #[inline]
1070 fn to_any(self) -> AnyCalendar {
1071 AnyCalendar::Dangi(self)
1072 }
1073 #[inline]
1074 fn kind(&self) -> AnyCalendarKind {
1075 AnyCalendarKind::Dangi
1076 }
1077 #[inline]
1078 fn from_any(any: AnyCalendar) -> Result<Self, AnyCalendar> {
1079 if let AnyCalendar::Dangi(cal) = any {
1080 Ok(cal)
1081 } else {
1082 Err(any)
1083 }
1084 }
1085 #[inline]
1086 fn from_any_ref(any: &AnyCalendar) -> Option<&Self> {
1087 if let AnyCalendar::Dangi(cal) = any {
1088 Some(cal)
1089 } else {
1090 None
1091 }
1092 }
1093 #[inline]
1094 fn date_to_any(&self, d: &Self::DateInner) -> AnyDateInner {
1095 AnyDateInner::Dangi(*d)
1096 }
1097}
1098
1099impl From<Dangi> for AnyCalendar {
1100 fn from(value: Dangi) -> AnyCalendar {
1101 value.to_any()
1102 }
1103}
1104
1105impl IntoAnyCalendar for Ethiopian {
1106 #[inline]
1108 fn to_any(self) -> AnyCalendar {
1109 AnyCalendar::Ethiopian(self)
1110 }
1111 #[inline]
1112 fn kind(&self) -> AnyCalendarKind {
1113 if self.0 {
1114 AnyCalendarKind::EthiopianAmeteAlem
1115 } else {
1116 AnyCalendarKind::Ethiopian
1117 }
1118 }
1119 #[inline]
1120 fn from_any(any: AnyCalendar) -> Result<Self, AnyCalendar> {
1121 if let AnyCalendar::Ethiopian(cal) = any {
1122 Ok(cal)
1123 } else {
1124 Err(any)
1125 }
1126 }
1127 #[inline]
1128 fn from_any_ref(any: &AnyCalendar) -> Option<&Self> {
1129 if let AnyCalendar::Ethiopian(cal) = any {
1130 Some(cal)
1131 } else {
1132 None
1133 }
1134 }
1135 #[inline]
1136 fn date_to_any(&self, d: &Self::DateInner) -> AnyDateInner {
1137 AnyDateInner::Ethiopian(*d)
1138 }
1139}
1140
1141impl From<Ethiopian> for AnyCalendar {
1142 fn from(value: Ethiopian) -> AnyCalendar {
1143 value.to_any()
1144 }
1145}
1146
1147impl IntoAnyCalendar for Gregorian {
1148 #[inline]
1149 fn to_any(self) -> AnyCalendar {
1150 AnyCalendar::Gregorian(Gregorian)
1151 }
1152 #[inline]
1153 fn kind(&self) -> AnyCalendarKind {
1154 AnyCalendarKind::Gregorian
1155 }
1156 #[inline]
1157 fn from_any(any: AnyCalendar) -> Result<Self, AnyCalendar> {
1158 if let AnyCalendar::Gregorian(cal) = any {
1159 Ok(cal)
1160 } else {
1161 Err(any)
1162 }
1163 }
1164 #[inline]
1165 fn from_any_ref(any: &AnyCalendar) -> Option<&Self> {
1166 if let AnyCalendar::Gregorian(cal) = any {
1167 Some(cal)
1168 } else {
1169 None
1170 }
1171 }
1172 #[inline]
1173 fn date_to_any(&self, d: &Self::DateInner) -> AnyDateInner {
1174 AnyDateInner::Gregorian(*d)
1175 }
1176}
1177
1178impl From<Gregorian> for AnyCalendar {
1179 fn from(value: Gregorian) -> AnyCalendar {
1180 value.to_any()
1181 }
1182}
1183
1184impl IntoAnyCalendar for Hebrew {
1185 #[inline]
1186 fn to_any(self) -> AnyCalendar {
1187 AnyCalendar::Hebrew(Hebrew)
1188 }
1189 #[inline]
1190 fn kind(&self) -> AnyCalendarKind {
1191 AnyCalendarKind::Hebrew
1192 }
1193 #[inline]
1194 fn from_any(any: AnyCalendar) -> Result<Self, AnyCalendar> {
1195 if let AnyCalendar::Hebrew(cal) = any {
1196 Ok(cal)
1197 } else {
1198 Err(any)
1199 }
1200 }
1201 #[inline]
1202 fn from_any_ref(any: &AnyCalendar) -> Option<&Self> {
1203 if let AnyCalendar::Hebrew(cal) = any {
1204 Some(cal)
1205 } else {
1206 None
1207 }
1208 }
1209 #[inline]
1210 fn date_to_any(&self, d: &Self::DateInner) -> AnyDateInner {
1211 AnyDateInner::Hebrew(*d)
1212 }
1213}
1214
1215impl From<Hebrew> for AnyCalendar {
1216 fn from(value: Hebrew) -> AnyCalendar {
1217 value.to_any()
1218 }
1219}
1220
1221impl IntoAnyCalendar for Indian {
1222 #[inline]
1223 fn to_any(self) -> AnyCalendar {
1224 AnyCalendar::Indian(Indian)
1225 }
1226 #[inline]
1227 fn kind(&self) -> AnyCalendarKind {
1228 AnyCalendarKind::Indian
1229 }
1230 #[inline]
1231 fn from_any(any: AnyCalendar) -> Result<Self, AnyCalendar> {
1232 if let AnyCalendar::Indian(cal) = any {
1233 Ok(cal)
1234 } else {
1235 Err(any)
1236 }
1237 }
1238 #[inline]
1239 fn from_any_ref(any: &AnyCalendar) -> Option<&Self> {
1240 if let AnyCalendar::Indian(cal) = any {
1241 Some(cal)
1242 } else {
1243 None
1244 }
1245 }
1246 #[inline]
1247 fn date_to_any(&self, d: &Self::DateInner) -> AnyDateInner {
1248 AnyDateInner::Indian(*d)
1249 }
1250}
1251
1252impl From<Indian> for AnyCalendar {
1253 fn from(value: Indian) -> AnyCalendar {
1254 value.to_any()
1255 }
1256}
1257
1258impl IntoAnyCalendar for HijriTabular {
1259 #[inline]
1260 fn to_any(self) -> AnyCalendar {
1261 AnyCalendar::HijriTabular(self)
1262 }
1263 #[inline]
1264 fn kind(&self) -> AnyCalendarKind {
1265 match (self.leap_years, self.epoch) {
1266 (HijriTabularLeapYears::TypeII, HijriTabularEpoch::Friday) => {
1267 AnyCalendarKind::HijriTabularTypeIIFriday
1268 }
1269 (HijriTabularLeapYears::TypeII, HijriTabularEpoch::Thursday) => {
1270 AnyCalendarKind::HijriTabularTypeIIThursday
1271 }
1272 }
1273 }
1274 #[inline]
1275 fn from_any(any: AnyCalendar) -> Result<Self, AnyCalendar> {
1276 if let AnyCalendar::HijriTabular(cal) = any {
1277 Ok(cal)
1278 } else {
1279 Err(any)
1280 }
1281 }
1282 #[inline]
1283 fn from_any_ref(any: &AnyCalendar) -> Option<&Self> {
1284 if let AnyCalendar::HijriTabular(cal) = any {
1285 Some(cal)
1286 } else {
1287 None
1288 }
1289 }
1290 #[inline]
1291 fn date_to_any(&self, d: &Self::DateInner) -> AnyDateInner {
1292 AnyDateInner::HijriTabular(*d, self.leap_years, self.epoch)
1293 }
1294}
1295
1296impl From<HijriTabular> for AnyCalendar {
1297 fn from(value: HijriTabular) -> AnyCalendar {
1298 value.to_any()
1299 }
1300}
1301
1302impl IntoAnyCalendar for HijriSimulated {
1303 #[inline]
1304 fn to_any(self) -> AnyCalendar {
1305 AnyCalendar::HijriSimulated(self)
1306 }
1307 #[inline]
1308 fn kind(&self) -> AnyCalendarKind {
1309 match self.location {
1310 HijriSimulatedLocation::Mecca => AnyCalendarKind::HijriSimulatedMecca,
1311 }
1312 }
1313 #[inline]
1314 fn from_any(any: AnyCalendar) -> Result<Self, AnyCalendar> {
1315 if let AnyCalendar::HijriSimulated(cal) = any {
1316 Ok(cal)
1317 } else {
1318 Err(any)
1319 }
1320 }
1321 #[inline]
1322 fn from_any_ref(any: &AnyCalendar) -> Option<&Self> {
1323 if let AnyCalendar::HijriSimulated(cal) = any {
1324 Some(cal)
1325 } else {
1326 None
1327 }
1328 }
1329 #[inline]
1330 fn date_to_any(&self, d: &Self::DateInner) -> AnyDateInner {
1331 AnyDateInner::HijriSimulated(*d)
1332 }
1333}
1334
1335impl From<HijriSimulated> for AnyCalendar {
1336 fn from(value: HijriSimulated) -> AnyCalendar {
1337 value.to_any()
1338 }
1339}
1340
1341impl IntoAnyCalendar for HijriUmmAlQura {
1342 #[inline]
1343 fn to_any(self) -> AnyCalendar {
1344 AnyCalendar::HijriUmmAlQura(self)
1345 }
1346 #[inline]
1347 fn kind(&self) -> AnyCalendarKind {
1348 AnyCalendarKind::HijriUmmAlQura
1349 }
1350 #[inline]
1351 fn from_any(any: AnyCalendar) -> Result<Self, AnyCalendar> {
1352 if let AnyCalendar::HijriUmmAlQura(cal) = any {
1353 Ok(cal)
1354 } else {
1355 Err(any)
1356 }
1357 }
1358 #[inline]
1359 fn from_any_ref(any: &AnyCalendar) -> Option<&Self> {
1360 if let AnyCalendar::HijriUmmAlQura(cal) = any {
1361 Some(cal)
1362 } else {
1363 None
1364 }
1365 }
1366 #[inline]
1367 fn date_to_any(&self, d: &Self::DateInner) -> AnyDateInner {
1368 AnyDateInner::HijriUmmAlQura(*d)
1369 }
1370}
1371
1372impl From<HijriUmmAlQura> for AnyCalendar {
1373 fn from(value: HijriUmmAlQura) -> AnyCalendar {
1374 value.to_any()
1375 }
1376}
1377
1378impl IntoAnyCalendar for Iso {
1379 #[inline]
1380 fn to_any(self) -> AnyCalendar {
1381 AnyCalendar::Iso(Iso)
1382 }
1383 #[inline]
1384 fn kind(&self) -> AnyCalendarKind {
1385 AnyCalendarKind::Iso
1386 }
1387 #[inline]
1388 fn from_any(any: AnyCalendar) -> Result<Self, AnyCalendar> {
1389 if let AnyCalendar::Iso(cal) = any {
1390 Ok(cal)
1391 } else {
1392 Err(any)
1393 }
1394 }
1395 #[inline]
1396 fn from_any_ref(any: &AnyCalendar) -> Option<&Self> {
1397 if let AnyCalendar::Iso(cal) = any {
1398 Some(cal)
1399 } else {
1400 None
1401 }
1402 }
1403 #[inline]
1404 fn date_to_any(&self, d: &Self::DateInner) -> AnyDateInner {
1405 AnyDateInner::Iso(*d)
1406 }
1407}
1408
1409impl From<Iso> for AnyCalendar {
1410 fn from(value: Iso) -> AnyCalendar {
1411 value.to_any()
1412 }
1413}
1414
1415impl IntoAnyCalendar for Japanese {
1416 #[inline]
1417 fn to_any(self) -> AnyCalendar {
1418 AnyCalendar::Japanese(self)
1419 }
1420 #[inline]
1421 fn kind(&self) -> AnyCalendarKind {
1422 AnyCalendarKind::Japanese
1423 }
1424 #[inline]
1425 fn from_any(any: AnyCalendar) -> Result<Self, AnyCalendar> {
1426 if let AnyCalendar::Japanese(cal) = any {
1427 Ok(cal)
1428 } else {
1429 Err(any)
1430 }
1431 }
1432 #[inline]
1433 fn from_any_ref(any: &AnyCalendar) -> Option<&Self> {
1434 if let AnyCalendar::Japanese(cal) = any {
1435 Some(cal)
1436 } else {
1437 None
1438 }
1439 }
1440 #[inline]
1441 fn date_to_any(&self, d: &Self::DateInner) -> AnyDateInner {
1442 AnyDateInner::Japanese(*d)
1443 }
1444}
1445
1446impl From<Japanese> for AnyCalendar {
1447 fn from(value: Japanese) -> AnyCalendar {
1448 value.to_any()
1449 }
1450}
1451
1452impl IntoAnyCalendar for JapaneseExtended {
1453 #[inline]
1454 fn to_any(self) -> AnyCalendar {
1455 AnyCalendar::JapaneseExtended(self)
1456 }
1457 #[inline]
1458 fn kind(&self) -> AnyCalendarKind {
1459 AnyCalendarKind::JapaneseExtended
1460 }
1461 #[inline]
1462 fn from_any(any: AnyCalendar) -> Result<Self, AnyCalendar> {
1463 if let AnyCalendar::JapaneseExtended(cal) = any {
1464 Ok(cal)
1465 } else {
1466 Err(any)
1467 }
1468 }
1469 #[inline]
1470 fn from_any_ref(any: &AnyCalendar) -> Option<&Self> {
1471 if let AnyCalendar::JapaneseExtended(cal) = any {
1472 Some(cal)
1473 } else {
1474 None
1475 }
1476 }
1477 #[inline]
1478 fn date_to_any(&self, d: &Self::DateInner) -> AnyDateInner {
1479 AnyDateInner::JapaneseExtended(*d)
1480 }
1481}
1482
1483impl From<JapaneseExtended> for AnyCalendar {
1484 fn from(value: JapaneseExtended) -> AnyCalendar {
1485 value.to_any()
1486 }
1487}
1488
1489impl IntoAnyCalendar for Persian {
1490 #[inline]
1491 fn to_any(self) -> AnyCalendar {
1492 AnyCalendar::Persian(Persian)
1493 }
1494 #[inline]
1495 fn kind(&self) -> AnyCalendarKind {
1496 AnyCalendarKind::Persian
1497 }
1498 #[inline]
1499 fn from_any(any: AnyCalendar) -> Result<Self, AnyCalendar> {
1500 if let AnyCalendar::Persian(cal) = any {
1501 Ok(cal)
1502 } else {
1503 Err(any)
1504 }
1505 }
1506 #[inline]
1507 fn from_any_ref(any: &AnyCalendar) -> Option<&Self> {
1508 if let AnyCalendar::Persian(cal) = any {
1509 Some(cal)
1510 } else {
1511 None
1512 }
1513 }
1514 #[inline]
1515 fn date_to_any(&self, d: &Self::DateInner) -> AnyDateInner {
1516 AnyDateInner::Persian(*d)
1517 }
1518}
1519
1520impl From<Persian> for AnyCalendar {
1521 fn from(value: Persian) -> AnyCalendar {
1522 value.to_any()
1523 }
1524}
1525
1526impl IntoAnyCalendar for Roc {
1527 #[inline]
1528 fn to_any(self) -> AnyCalendar {
1529 AnyCalendar::Roc(Roc)
1530 }
1531 #[inline]
1532 fn kind(&self) -> AnyCalendarKind {
1533 AnyCalendarKind::Roc
1534 }
1535 #[inline]
1536 fn from_any(any: AnyCalendar) -> Result<Self, AnyCalendar> {
1537 if let AnyCalendar::Roc(cal) = any {
1538 Ok(cal)
1539 } else {
1540 Err(any)
1541 }
1542 }
1543 #[inline]
1544 fn from_any_ref(any: &AnyCalendar) -> Option<&Self> {
1545 if let AnyCalendar::Roc(cal) = any {
1546 Some(cal)
1547 } else {
1548 None
1549 }
1550 }
1551 #[inline]
1552 fn date_to_any(&self, d: &Self::DateInner) -> AnyDateInner {
1553 AnyDateInner::Roc(*d)
1554 }
1555}
1556
1557impl From<Roc> for AnyCalendar {
1558 fn from(value: Roc) -> AnyCalendar {
1559 value.to_any()
1560 }
1561}
1562
1563#[cfg(test)]
1564mod tests {
1565 use tinystr::tinystr;
1566 use types::MonthCode;
1567
1568 use super::*;
1569 use crate::Ref;
1570
1571 #[track_caller]
1572 fn single_test_roundtrip(
1573 calendar: Ref<AnyCalendar>,
1574 era: Option<(&str, Option<u8>)>,
1575 year: i32,
1576 month_code: &str,
1577 day: u8,
1578 ) {
1579 let month = types::MonthCode(month_code.parse().expect("month code must parse"));
1580
1581 let date = Date::try_new_from_codes(era.map(|x| x.0), year, month, day, calendar)
1582 .unwrap_or_else(|e| {
1583 panic!(
1584 "Failed to construct date for {} with {era:?}, {year}, {month}, {day}: {e:?}",
1585 calendar.debug_name(),
1586 )
1587 });
1588
1589 let roundtrip_year = date.year();
1590 let roundtrip_year = roundtrip_year.era_year_or_related_iso();
1592 let roundtrip_month = date.month().standard_code;
1593 let roundtrip_day = date.day_of_month().0;
1594
1595 assert_eq!(
1596 (year, month, day),
1597 (roundtrip_year, roundtrip_month, roundtrip_day),
1598 "Failed to roundtrip for calendar {}",
1599 calendar.debug_name()
1600 );
1601
1602 if let Some((era_code, era_index)) = era {
1603 let roundtrip_era_year = date.year().era().expect("year type should be era");
1604 assert_eq!(
1605 (era_code, era_index),
1606 (
1607 roundtrip_era_year.era.as_str(),
1608 roundtrip_era_year.era_index
1609 ),
1610 "Failed to roundtrip era for calendar {}",
1611 calendar.debug_name()
1612 )
1613 }
1614
1615 let iso = date.to_iso();
1616 let reconstructed = Date::new_from_iso(iso, calendar);
1617 assert_eq!(
1618 date, reconstructed,
1619 "Failed to roundtrip via iso with {era:?}, {year}, {month}, {day}"
1620 )
1621 }
1622
1623 #[track_caller]
1624 fn single_test_error(
1625 calendar: Ref<AnyCalendar>,
1626 era: Option<(&str, Option<u8>)>,
1627 year: i32,
1628 month_code: &str,
1629 day: u8,
1630 error: DateError,
1631 ) {
1632 let month = types::MonthCode(month_code.parse().expect("month code must parse"));
1633
1634 let date = Date::try_new_from_codes(era.map(|x| x.0), year, month, day, calendar);
1635 assert_eq!(
1636 date,
1637 Err(error),
1638 "Construction with {era:?}, {year}, {month}, {day} did not return {error:?}"
1639 )
1640 }
1641
1642 #[test]
1643 fn test_any_construction() {
1644 let buddhist = AnyCalendar::new(AnyCalendarKind::Buddhist);
1645 let chinese = AnyCalendar::new(AnyCalendarKind::Chinese);
1646 let coptic = AnyCalendar::new(AnyCalendarKind::Coptic);
1647 let dangi = AnyCalendar::new(AnyCalendarKind::Dangi);
1648 let ethioaa = AnyCalendar::new(AnyCalendarKind::EthiopianAmeteAlem);
1649 let ethiopian = AnyCalendar::new(AnyCalendarKind::Ethiopian);
1650 let gregorian = AnyCalendar::new(AnyCalendarKind::Gregorian);
1651 let hebrew = AnyCalendar::new(AnyCalendarKind::Hebrew);
1652 let indian = AnyCalendar::new(AnyCalendarKind::Indian);
1653 let hijri_civil: AnyCalendar = AnyCalendar::new(AnyCalendarKind::HijriTabularTypeIIFriday);
1654 let hijri_simulated: AnyCalendar = AnyCalendar::new(AnyCalendarKind::HijriSimulatedMecca);
1655 let hijri_astronomical: AnyCalendar =
1656 AnyCalendar::new(AnyCalendarKind::HijriTabularTypeIIThursday);
1657 let hijri_umm_al_qura: AnyCalendar = AnyCalendar::new(AnyCalendarKind::HijriUmmAlQura);
1658 let japanese = AnyCalendar::new(AnyCalendarKind::Japanese);
1659 let japanext = AnyCalendar::new(AnyCalendarKind::JapaneseExtended);
1660 let persian = AnyCalendar::new(AnyCalendarKind::Persian);
1661 let roc = AnyCalendar::new(AnyCalendarKind::Roc);
1662 let buddhist = Ref(&buddhist);
1663 let chinese = Ref(&chinese);
1664 let coptic = Ref(&coptic);
1665 let dangi = Ref(&dangi);
1666 let ethioaa = Ref(ðioaa);
1667 let ethiopian = Ref(ðiopian);
1668 let gregorian = Ref(&gregorian);
1669 let hebrew = Ref(&hebrew);
1670 let indian = Ref(&indian);
1671 let hijri_civil = Ref(&hijri_civil);
1672 let hijri_simulated = Ref(&hijri_simulated);
1673 let hijri_astronomical = Ref(&hijri_astronomical);
1674 let hijri_umm_al_qura = Ref(&hijri_umm_al_qura);
1675 let japanese = Ref(&japanese);
1676 let japanext = Ref(&japanext);
1677 let persian = Ref(&persian);
1678 let roc = Ref(&roc);
1679
1680 single_test_roundtrip(buddhist, Some(("be", Some(0))), 100, "M03", 1);
1681 single_test_roundtrip(buddhist, None, 2000, "M03", 1);
1682 single_test_roundtrip(buddhist, Some(("be", Some(0))), -100, "M03", 1);
1683 single_test_error(
1684 buddhist,
1685 Some(("be", Some(0))),
1686 100,
1687 "M13",
1688 1,
1689 DateError::UnknownMonthCode(MonthCode(tinystr!(4, "M13"))),
1690 );
1691
1692 single_test_roundtrip(coptic, Some(("am", Some(0))), 100, "M03", 1);
1693 single_test_roundtrip(coptic, None, 2000, "M03", 1);
1694 single_test_roundtrip(coptic, Some(("am", Some(0))), -99, "M03", 1);
1695 single_test_roundtrip(coptic, Some(("am", Some(0))), 100, "M13", 1);
1696 single_test_error(
1697 coptic,
1698 Some(("am", Some(0))),
1699 100,
1700 "M14",
1701 1,
1702 DateError::UnknownMonthCode(MonthCode(tinystr!(4, "M14"))),
1703 );
1704
1705 single_test_roundtrip(ethiopian, Some(("am", Some(1))), 100, "M03", 1);
1706 single_test_roundtrip(ethiopian, None, 2000, "M03", 1);
1707 single_test_roundtrip(ethiopian, Some(("am", Some(1))), 2000, "M13", 1);
1708 single_test_roundtrip(ethiopian, Some(("aa", Some(0))), 5400, "M03", 1);
1709 single_test_error(
1710 ethiopian,
1711 Some(("am", Some(0))),
1712 0,
1713 "M03",
1714 1,
1715 DateError::Range {
1716 field: "year",
1717 value: 0,
1718 min: 1,
1719 max: i32::MAX,
1720 },
1721 );
1722 single_test_error(
1723 ethiopian,
1724 Some(("aa", Some(0))),
1725 5600,
1726 "M03",
1727 1,
1728 DateError::Range {
1729 field: "year",
1730 value: 5600,
1731 min: i32::MIN,
1732 max: 5500,
1733 },
1734 );
1735 single_test_error(
1736 ethiopian,
1737 Some(("am", Some(0))),
1738 100,
1739 "M14",
1740 1,
1741 DateError::UnknownMonthCode(MonthCode(tinystr!(4, "M14"))),
1742 );
1743
1744 single_test_roundtrip(ethioaa, Some(("aa", Some(0))), 7000, "M13", 1);
1745 single_test_roundtrip(ethioaa, None, 7000, "M13", 1);
1746 single_test_roundtrip(ethioaa, Some(("aa", Some(0))), 100, "M03", 1);
1747 single_test_error(
1748 ethiopian,
1749 Some(("aa", Some(0))),
1750 100,
1751 "M14",
1752 1,
1753 DateError::UnknownMonthCode(MonthCode(tinystr!(4, "M14"))),
1754 );
1755
1756 single_test_roundtrip(gregorian, Some(("ce", Some(1))), 100, "M03", 1);
1757 single_test_roundtrip(gregorian, None, 2000, "M03", 1);
1758 single_test_roundtrip(gregorian, Some(("bce", Some(0))), 100, "M03", 1);
1759 single_test_error(
1760 gregorian,
1761 Some(("ce", Some(1))),
1762 0,
1763 "M03",
1764 1,
1765 DateError::Range {
1766 field: "year",
1767 value: 0,
1768 min: 1,
1769 max: i32::MAX,
1770 },
1771 );
1772 single_test_error(
1773 gregorian,
1774 Some(("bce", Some(0))),
1775 0,
1776 "M03",
1777 1,
1778 DateError::Range {
1779 field: "year",
1780 value: 0,
1781 min: 1,
1782 max: i32::MAX,
1783 },
1784 );
1785
1786 single_test_error(
1787 gregorian,
1788 Some(("bce", Some(0))),
1789 100,
1790 "M13",
1791 1,
1792 DateError::UnknownMonthCode(MonthCode(tinystr!(4, "M13"))),
1793 );
1794
1795 single_test_roundtrip(indian, Some(("shaka", Some(0))), 100, "M03", 1);
1796 single_test_roundtrip(indian, None, 2000, "M12", 1);
1797 single_test_roundtrip(indian, None, -100, "M03", 1);
1798 single_test_roundtrip(indian, Some(("shaka", Some(0))), 0, "M03", 1);
1799 single_test_error(
1800 indian,
1801 Some(("shaka", Some(0))),
1802 100,
1803 "M13",
1804 1,
1805 DateError::UnknownMonthCode(MonthCode(tinystr!(4, "M13"))),
1806 );
1807
1808 single_test_roundtrip(chinese, None, 400, "M02", 5);
1809 single_test_roundtrip(chinese, None, 4660, "M07", 29);
1810 single_test_roundtrip(chinese, None, -100, "M11", 12);
1811 single_test_error(
1812 chinese,
1813 None,
1814 4658,
1815 "M13",
1816 1,
1817 DateError::UnknownMonthCode(MonthCode(tinystr!(4, "M13"))),
1818 );
1819
1820 single_test_roundtrip(dangi, None, 400, "M02", 5);
1821 single_test_roundtrip(dangi, None, 4660, "M08", 29);
1822 single_test_roundtrip(dangi, None, -1300, "M11", 12);
1823 single_test_error(
1824 dangi,
1825 None,
1826 10393,
1827 "M00L",
1828 1,
1829 DateError::UnknownMonthCode(MonthCode(tinystr!(4, "M00L"))),
1830 );
1831
1832 single_test_roundtrip(japanese, Some(("reiwa", None)), 3, "M03", 1);
1833 single_test_roundtrip(japanese, Some(("heisei", None)), 6, "M12", 1);
1834 single_test_roundtrip(japanese, Some(("meiji", None)), 10, "M03", 1);
1835 single_test_roundtrip(japanese, Some(("ce", None)), 1000, "M03", 1);
1836 single_test_roundtrip(japanese, None, 1000, "M03", 1);
1837 single_test_roundtrip(japanese, Some(("bce", None)), 10, "M03", 1);
1838 single_test_error(
1839 japanese,
1840 Some(("ce", None)),
1841 0,
1842 "M03",
1843 1,
1844 DateError::Range {
1845 field: "year",
1846 value: 0,
1847 min: 1,
1848 max: i32::MAX,
1849 },
1850 );
1851 single_test_error(
1852 japanese,
1853 Some(("bce", Some(0))),
1854 0,
1855 "M03",
1856 1,
1857 DateError::Range {
1858 field: "year",
1859 value: 0,
1860 min: 1,
1861 max: i32::MAX,
1862 },
1863 );
1864
1865 single_test_error(
1866 japanese,
1867 Some(("reiwa", None)),
1868 2,
1869 "M13",
1870 1,
1871 DateError::UnknownMonthCode(MonthCode(tinystr!(4, "M13"))),
1872 );
1873
1874 single_test_roundtrip(japanext, Some(("reiwa", None)), 3, "M03", 1);
1875 single_test_roundtrip(japanext, Some(("heisei", None)), 6, "M12", 1);
1876 single_test_roundtrip(japanext, Some(("meiji", None)), 10, "M03", 1);
1877 single_test_roundtrip(japanext, Some(("tenpyokampo-749", None)), 1, "M04", 20);
1878 single_test_roundtrip(japanext, Some(("ce", None)), 100, "M03", 1);
1879 single_test_roundtrip(japanext, Some(("bce", None)), 10, "M03", 1);
1880 single_test_error(
1881 japanext,
1882 Some(("ce", None)),
1883 0,
1884 "M03",
1885 1,
1886 DateError::Range {
1887 field: "year",
1888 value: 0,
1889 min: 1,
1890 max: i32::MAX,
1891 },
1892 );
1893 single_test_error(
1894 japanext,
1895 Some(("bce", Some(0))),
1896 0,
1897 "M03",
1898 1,
1899 DateError::Range {
1900 field: "year",
1901 value: 0,
1902 min: 1,
1903 max: i32::MAX,
1904 },
1905 );
1906
1907 single_test_error(
1908 japanext,
1909 Some(("reiwa", None)),
1910 2,
1911 "M13",
1912 1,
1913 DateError::UnknownMonthCode(MonthCode(tinystr!(4, "M13"))),
1914 );
1915
1916 single_test_roundtrip(persian, Some(("ap", Some(0))), 477, "M03", 1);
1917 single_test_roundtrip(persian, None, 2083, "M07", 21);
1918 single_test_roundtrip(persian, Some(("ap", Some(0))), 1600, "M12", 20);
1919 single_test_error(
1920 persian,
1921 Some(("ap", Some(0))),
1922 100,
1923 "M9",
1924 1,
1925 DateError::UnknownMonthCode(MonthCode(tinystr!(4, "M9"))),
1926 );
1927
1928 single_test_roundtrip(hebrew, Some(("am", Some(0))), 5773, "M03", 1);
1929 single_test_roundtrip(hebrew, None, 4993, "M07", 21);
1930 single_test_roundtrip(hebrew, Some(("am", Some(0))), 5012, "M12", 20);
1931 single_test_error(
1932 hebrew,
1933 Some(("am", Some(0))),
1934 100,
1935 "M9",
1936 1,
1937 DateError::UnknownMonthCode(MonthCode(tinystr!(4, "M9"))),
1938 );
1939
1940 single_test_roundtrip(roc, Some(("roc", Some(1))), 10, "M05", 3);
1941 single_test_roundtrip(roc, Some(("broc", Some(0))), 15, "M01", 10);
1942 single_test_roundtrip(roc, None, 100, "M10", 30);
1943
1944 single_test_roundtrip(hijri_simulated, Some(("ah", Some(0))), 477, "M03", 1);
1945 single_test_roundtrip(hijri_simulated, None, 2083, "M07", 21);
1946 single_test_roundtrip(hijri_simulated, Some(("ah", Some(0))), 1600, "M12", 20);
1947 single_test_error(
1948 hijri_simulated,
1949 Some(("ah", Some(0))),
1950 100,
1951 "M9",
1952 1,
1953 DateError::UnknownMonthCode(MonthCode(tinystr!(4, "M9"))),
1954 );
1955
1956 single_test_roundtrip(hijri_civil, Some(("ah", Some(0))), 477, "M03", 1);
1957 single_test_roundtrip(hijri_civil, None, 2083, "M07", 21);
1958 single_test_roundtrip(hijri_civil, Some(("ah", Some(0))), 1600, "M12", 20);
1959 single_test_error(
1960 hijri_civil,
1961 Some(("ah", Some(0))),
1962 100,
1963 "M9",
1964 1,
1965 DateError::UnknownMonthCode(MonthCode(tinystr!(4, "M9"))),
1966 );
1967
1968 single_test_roundtrip(hijri_umm_al_qura, Some(("ah", Some(0))), 477, "M03", 1);
1969 single_test_roundtrip(hijri_umm_al_qura, None, 2083, "M07", 21);
1970 single_test_roundtrip(hijri_umm_al_qura, Some(("ah", Some(0))), 1600, "M12", 20);
1971 single_test_error(
1972 hijri_umm_al_qura,
1973 Some(("ah", Some(0))),
1974 100,
1975 "M9",
1976 1,
1977 DateError::UnknownMonthCode(MonthCode(tinystr!(4, "M9"))),
1978 );
1979
1980 single_test_roundtrip(hijri_astronomical, Some(("ah", Some(0))), 477, "M03", 1);
1981 single_test_roundtrip(hijri_astronomical, None, 2083, "M07", 21);
1982 single_test_roundtrip(hijri_astronomical, Some(("ah", Some(0))), 1600, "M12", 20);
1983 single_test_error(
1984 hijri_astronomical,
1985 Some(("ah", Some(0))),
1986 100,
1987 "M9",
1988 1,
1989 DateError::UnknownMonthCode(MonthCode(tinystr!(4, "M9"))),
1990 );
1991 }
1992}