usecrate::cal::abstract_gregorian::{impl_with_abstract_gregorian, GregorianYears}; usecrate::calendar_arithmetic::ArithmeticDate; usecrate::error::UnknownEraError; usecrate::{types, Date, DateError, RangeError}; use tinystr::tinystr;
/// The [ISO-8601 Calendar](https://en.wikipedia.org/wiki/ISO_8601#Dates) /// /// This calendar is identical to the [`Gregorian`](super::Gregorian) calendar, /// except that it uses a single `default` era instead of `bce` and `ce`. /// /// This corresponds to the `"iso8601"` [CLDR calendar](https://unicode.org/reports/tr35/#UnicodeCalendarIdentifier). /// /// # Era codes /// /// This calendar uses a single era: `default` #[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] #[allow(clippy::exhaustive_structs)] // this type is stable pubstruct Iso;
impl Date<Iso> { /// Construct a new ISO date from integers. /// /// ```rust /// use icu::calendar::Date; /// /// let date_iso = Date::try_new_iso(1970, 1, 2) /// .expect("Failed to initialize ISO Date instance."); /// /// assert_eq!(date_iso.era_year().year, 1970); /// assert_eq!(date_iso.month().ordinal, 1); /// assert_eq!(date_iso.day_of_month().0, 2); /// ``` pubfn try_new_iso(year: i32, month: u8, day: u8) -> Result<Date<Iso>, RangeError> {
ArithmeticDate::new_gregorian::<IsoEra>(year, month, day)
.map(IsoDateInner)
.map(|i| Date::from_raw(i, Iso))
}
}
impl Iso { /// Construct a new ISO Calendar pubfn new() -> Self { Self
}
}
#[cfg(test)] mod test { usesuper::*; usecrate::types::{DateDuration, RataDie, Weekday}; usecrate::Calendar;
#[test] fn iso_overflow() { #[derive(Debug)] struct TestCase {
year: i32,
month: u8,
day: u8,
rd: RataDie,
saturating: bool,
} // Calculates the max possible year representable using i32::MAX as the RD let max_year = Iso.from_rata_die(RataDie::new(i32::MAX as i64)).0.year;
// Calculates the minimum possible year representable using i32::MIN as the RD // *Cannot be tested yet due to hard coded date not being available yet (see line 436) let min_year = -5879610;
for case in cases { let date = Date::try_new_iso(case.year, case.month, case.day).unwrap(); if !case.saturating {
assert_eq!(date.to_rata_die(), case.rd, "{case:?}");
}
assert_eq!(Date::from_rata_die(case.rd, Iso), date, "{case:?}");
}
}
// Calculates the minimum possible year representable using a large negative fixed date #[test] fn min_year() {
assert_eq!(
Date::from_rata_die(RataDie::big_negative(), Iso)
.year()
.era()
.unwrap()
.year,
i32::MIN
);
}
#[test] fn test_day_of_week() { // June 23, 2021 is a Wednesday
assert_eq!(
Date::try_new_iso(2021, 6, 23).unwrap().day_of_week(),
Weekday::Wednesday,
); // Feb 2, 1983 was a Wednesday
assert_eq!(
Date::try_new_iso(1983, 2, 2).unwrap().day_of_week(),
Weekday::Wednesday,
); // Jan 21, 2021 was a Tuesday
assert_eq!(
Date::try_new_iso(2020, 1, 21).unwrap().day_of_week(),
Weekday::Tuesday,
);
}
#[test] fn test_day_of_year() { // June 23, 2021 was day 174
assert_eq!(Date::try_new_iso(2021, 6, 23).unwrap().day_of_year().0, 174,); // June 23, 2020 was day 175
assert_eq!(Date::try_new_iso(2020, 6, 23).unwrap().day_of_year().0, 175,); // Feb 2, 1983 was a Wednesday
assert_eq!(Date::try_new_iso(1983, 2, 2).unwrap().day_of_year().0, 33,);
}
#[test] fn test_offset() { let today = Date::try_new_iso(2021, 6, 23).unwrap(); let today_plus_5000 = Date::try_new_iso(2035, 3, 2).unwrap(); let offset = today
.try_added_with_options(DateDuration::for_days(5000), Default::default())
.unwrap();
assert_eq!(offset, today_plus_5000);
let today = Date::try_new_iso(2021, 6, 23).unwrap(); let today_minus_5000 = Date::try_new_iso(2007, 10, 15).unwrap(); let offset = today
.try_added_with_options(DateDuration::for_days(-5000), Default::default())
.unwrap();
assert_eq!(offset, today_minus_5000);
}
#[test] fn test_offset_at_month_boundary() { let today = Date::try_new_iso(2020, 2, 28).unwrap(); let today_plus_2 = Date::try_new_iso(2020, 3, 1).unwrap(); let offset = today
.try_added_with_options(DateDuration::for_days(2), Default::default())
.unwrap();
assert_eq!(offset, today_plus_2);
let today = Date::try_new_iso(2020, 2, 28).unwrap(); let today_plus_3 = Date::try_new_iso(2020, 3, 2).unwrap(); let offset = today
.try_added_with_options(DateDuration::for_days(3), Default::default())
.unwrap();
assert_eq!(offset, today_plus_3);
let today = Date::try_new_iso(2020, 2, 28).unwrap(); let today_plus_1 = Date::try_new_iso(2020, 2, 29).unwrap(); let offset = today
.try_added_with_options(DateDuration::for_days(1), Default::default())
.unwrap();
assert_eq!(offset, today_plus_1);
let today = Date::try_new_iso(2019, 2, 28).unwrap(); let today_plus_2 = Date::try_new_iso(2019, 3, 2).unwrap(); let offset = today
.try_added_with_options(DateDuration::for_days(2), Default::default())
.unwrap();
assert_eq!(offset, today_plus_2);
let today = Date::try_new_iso(2019, 2, 28).unwrap(); let today_plus_1 = Date::try_new_iso(2019, 3, 1).unwrap(); let offset = today
.try_added_with_options(DateDuration::for_days(1), Default::default())
.unwrap();
assert_eq!(offset, today_plus_1);
let today = Date::try_new_iso(2020, 3, 1).unwrap(); let today_minus_1 = Date::try_new_iso(2020, 2, 29).unwrap(); let offset = today
.try_added_with_options(DateDuration::for_days(-1), Default::default())
.unwrap();
assert_eq!(offset, today_minus_1);
}
#[test] fn test_offset_handles_negative_month_offset() { let today = Date::try_new_iso(2020, 3, 1).unwrap(); let today_minus_2_months = Date::try_new_iso(2020, 1, 1).unwrap(); let offset = today
.try_added_with_options(DateDuration::for_months(-2), Default::default())
.unwrap();
assert_eq!(offset, today_minus_2_months);
let today = Date::try_new_iso(2020, 3, 1).unwrap(); let today_minus_4_months = Date::try_new_iso(2019, 11, 1).unwrap(); let offset = today
.try_added_with_options(DateDuration::for_months(-4), Default::default())
.unwrap();
assert_eq!(offset, today_minus_4_months);
let today = Date::try_new_iso(2020, 3, 1).unwrap(); let today_minus_24_months = Date::try_new_iso(2018, 3, 1).unwrap(); let offset = today
.try_added_with_options(DateDuration::for_months(-24), Default::default())
.unwrap();
assert_eq!(offset, today_minus_24_months);
let today = Date::try_new_iso(2020, 3, 1).unwrap(); let today_minus_27_months = Date::try_new_iso(2017, 12, 1).unwrap(); let offset = today
.try_added_with_options(DateDuration::for_months(-27), Default::default())
.unwrap();
assert_eq!(offset, today_minus_27_months);
}
#[test] fn test_offset_handles_out_of_bound_month_offset() { let today = Date::try_new_iso(2021, 1, 31).unwrap(); // since 2021/02/31 isn't a valid date, `offset_date` auto-adjusts by constraining to the last day in February let today_plus_1_month = Date::try_new_iso(2021, 2, 28).unwrap(); let offset = today
.try_added_with_options(DateDuration::for_months(1), Default::default())
.unwrap();
assert_eq!(offset, today_plus_1_month);
let today = Date::try_new_iso(2021, 1, 31).unwrap(); // since 2021/02/31 isn't a valid date, `offset_date` auto-adjusts by constraining to the last day in February // and then adding the days let today_plus_1_month_1_day = Date::try_new_iso(2021, 3, 1).unwrap(); let offset = today
.try_added_with_options(
DateDuration {
months: 1,
days: 1,
..Default::default()
},
Default::default(),
)
.unwrap();
assert_eq!(offset, today_plus_1_month_1_day);
}
#[test] fn test_iso_to_from_rd() { // Reminder: ISO year 0 is Gregorian year 1 BCE. // Year 0 is a leap year due to the 400-year rule. fn check(rd: i64, year: i32, month: u8, day: u8) { let rd = RataDie::new(rd);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.