// as it is hard to verify year flags in `NaiveDate::MIN` and `NaiveDate::MAX`, // we use a separate run-time test. #[test] fn test_date_bounds() { let calculated_min = NaiveDate::from_ymd_opt(MIN_YEAR, 1, 1).unwrap(); let calculated_max = NaiveDate::from_ymd_opt(MAX_YEAR, 12, 31).unwrap();
assert!(
NaiveDate::MIN == calculated_min, "`NaiveDate::MIN` should have year flag {:?}",
calculated_min.year_flags()
);
assert!(
NaiveDate::MAX == calculated_max, "`NaiveDate::MAX` should have year flag {:?} and ordinal {}",
calculated_max.year_flags(),
calculated_max.ordinal()
);
// let's also check that the entire range do not exceed 2^44 seconds // (sometimes used for bounding `TimeDelta` against overflow) let maxsecs = NaiveDate::MAX.signed_duration_since(NaiveDate::MIN).num_seconds(); let maxsecs = maxsecs + 86401; // also take care of DateTime
assert!(
maxsecs < (1 << MAX_BITS), "The entire `NaiveDate` range somehow exceeds 2^{MAX_BITS} seconds"
);
// add to leap day
assert_eq!(
NaiveDate::from_ymd_opt(2022, 10, 29).unwrap().checked_add_months(Months::new(16)),
Some(NaiveDate::from_ymd_opt(2024, 2, 29).unwrap())
);
// add into december
assert_eq!(
NaiveDate::from_ymd_opt(2022, 10, 31).unwrap().checked_add_months(Months::new(2)),
Some(NaiveDate::from_ymd_opt(2022, 12, 31).unwrap())
);
// sub into december
assert_eq!(
NaiveDate::from_ymd_opt(2022, 10, 31).unwrap().checked_sub_months(Months::new(10)),
Some(NaiveDate::from_ymd_opt(2021, 12, 31).unwrap())
);
// add into january
assert_eq!(
NaiveDate::from_ymd_opt(2022, 8, 3).unwrap().checked_add_months(Months::new(5)),
Some(NaiveDate::from_ymd_opt(2023, 1, 3).unwrap())
);
// sub into january
assert_eq!(
NaiveDate::from_ymd_opt(2022, 8, 3).unwrap().checked_sub_months(Months::new(7)),
Some(NaiveDate::from_ymd_opt(2022, 1, 3).unwrap())
);
}
#[test] fn test_readme_doomsday() { for y in NaiveDate::MIN.year()..=NaiveDate::MAX.year() { // even months let d4 = NaiveDate::from_ymd_opt(y, 4, 4).unwrap(); let d6 = NaiveDate::from_ymd_opt(y, 6, 6).unwrap(); let d8 = NaiveDate::from_ymd_opt(y, 8, 8).unwrap(); let d10 = NaiveDate::from_ymd_opt(y, 10, 10).unwrap(); let d12 = NaiveDate::from_ymd_opt(y, 12, 12).unwrap();
// nine to five, seven-eleven let d59 = NaiveDate::from_ymd_opt(y, 5, 9).unwrap(); let d95 = NaiveDate::from_ymd_opt(y, 9, 5).unwrap(); let d711 = NaiveDate::from_ymd_opt(y, 7, 11).unwrap(); let d117 = NaiveDate::from_ymd_opt(y, 11, 7).unwrap();
// "March 0" let d30 = NaiveDate::from_ymd_opt(y, 3, 1).unwrap().pred_opt().unwrap();
#[test] fn test_date_from_isoywd_and_iso_week() { for year in2000..2401 { for week in1..54 { for &weekday in [
Weekday::Mon,
Weekday::Tue,
Weekday::Wed,
Weekday::Thu,
Weekday::Fri,
Weekday::Sat,
Weekday::Sun,
]
.iter()
{ let d = NaiveDate::from_isoywd_opt(year, week, weekday); iflet Some(d) = d {
assert_eq!(d.weekday(), weekday); let w = d.iso_week();
assert_eq!(w.year(), year);
assert_eq!(w.week(), week);
}
}
}
}
for year in2000..2401 { for month in1..13 { for day in1..32 { let d = NaiveDate::from_ymd_opt(year, month, day); iflet Some(d) = d { let w = d.iso_week(); let d_ = NaiveDate::from_isoywd_opt(w.year(), w.week(), d.weekday());
assert_eq!(d, d_.unwrap());
}
}
}
}
}
// the format specifier should have no effect on `NaiveTime`
assert_eq!(format!("{:+30?}", NaiveDate::from_ymd_opt(1234, 5, 6).unwrap()), "1234-05-06");
assert_eq!(format!("{:30?}", NaiveDate::from_ymd_opt(12345, 6, 7).unwrap()), "+12345-06-07");
}
#[test] fn test_date_from_str() { // valid cases let valid = [ "-0000000123456-1-2", " -123456 - 1 - 2 ", "-12345-1-2", "-1234-12-31", "-7-6-5", "350-2-28", "360-02-29", "0360-02-29", "2015-2 -18", "2015-02-18", "+70-2-18", "+70000-2-18", "+00007-2-18",
]; for &s in &valid {
eprintln!("test_date_from_str valid {s:?}"); let d = match s.parse::<NaiveDate>() {
Ok(d) => d,
Err(e) => panic!("parsing `{s}` has failed: {e}"),
};
eprintln!("d {d:?} (NaiveDate)"); let s_ = format!("{d:?}");
eprintln!("s_ {s_:?}"); // `s` and `s_` may differ, but `s.parse()` and `s_.parse()` must be same let d_ = match s_.parse::<NaiveDate>() {
Ok(d) => d,
Err(e) => {
panic!("`{s}` is parsed into `{d:?}`, but reparsing that has failed: {e}")
}
};
eprintln!("d_ {d_:?} (NaiveDate)");
assert!(
d == d_, "`{s}` is parsed into `{d:?}`, but reparsed result \
`{d_:?}` does not match"
);
}
// some invalid cases // since `ParseErrorKind` is private, all we can do is to check if there was an error let invalid = [ "", // empty "x", // invalid "Fri, 09 Aug 2013 GMT", // valid date, wrong format "Sat Jun 30 2012", // valid date, wrong format "1441497364.649", // valid datetime, wrong format "+1441497364.649", // valid datetime, wrong format "+1441497364", // valid datetime, wrong format "2014/02/03", // valid date, wrong format "2014", // datetime missing data "2014-01", // datetime missing data "2014-01-00", // invalid day "2014-11-32", // invalid day "2014-13-01", // invalid month "2014-13-57", // invalid month, day "9999999-9-9", // invalid year (out of bounds)
]; for &s in &invalid {
eprintln!("test_date_from_str invalid {s:?}");
assert!(s.parse::<NaiveDate>().is_err());
}
}
#[test] fn test_date_parse_from_str() { let ymd = |y, m, d| NaiveDate::from_ymd_opt(y, m, d).unwrap();
assert_eq!(
NaiveDate::parse_from_str("2014-5-7T12:34:56+09:30", "%Y-%m-%dT%H:%M:%S%z"),
Ok(ymd(2014, 5, 7))
); // ignore time and offset
assert_eq!(
NaiveDate::parse_from_str("2015-W06-1=2015-033 Q1", "%G-W%V-%u = %Y-%j Q%q"),
Ok(ymd(2015, 2, 2))
);
assert_eq!(NaiveDate::parse_from_str("Fri, 09 Aug 13", "%a, %d %b %y"), Ok(ymd(2013, 8, 9)));
assert!(NaiveDate::parse_from_str("Sat, 09 Aug 2013", "%a, %d %b %Y").is_err());
assert!(NaiveDate::parse_from_str("2014-57", "%Y-%m-%d").is_err());
assert!(NaiveDate::parse_from_str("2014", "%Y").is_err()); // insufficient
#[test] fn test_weeks_from() { // tests per: https://github.com/chronotope/chrono/issues/961 // these internally use `weeks_from` via the parsing infrastructure
assert_eq!(
NaiveDate::parse_from_str("2020-01-0", "%Y-%W-%w").ok(),
NaiveDate::from_ymd_opt(2020, 1, 12),
);
assert_eq!(
NaiveDate::parse_from_str("2019-01-0", "%Y-%W-%w").ok(),
NaiveDate::from_ymd_opt(2019, 1, 13),
);
// direct tests for (y, starts_on) in &[
(2019, Weekday::Tue),
(2020, Weekday::Wed),
(2021, Weekday::Fri),
(2022, Weekday::Sat),
(2023, Weekday::Sun),
(2024, Weekday::Mon),
(2025, Weekday::Wed),
(2026, Weekday::Thu),
] { for day in &[
Weekday::Mon,
Weekday::Tue,
Weekday::Wed,
Weekday::Thu,
Weekday::Fri,
Weekday::Sat,
Weekday::Sun,
] {
assert_eq!(
NaiveDate::from_ymd_opt(*y, 1, 1).map(|d| d.weeks_from(*day)),
Some(if day == starts_on { 1 } else { 0 })
);
// last day must always be in week 52 or 53
assert!(
[52, 53].contains(&NaiveDate::from_ymd_opt(*y, 12, 31).unwrap().weeks_from(*day)),
);
}
}
let base = NaiveDate::from_ymd_opt(2019, 1, 1).unwrap();
// 400 years covers all year types for day in &[
Weekday::Mon,
Weekday::Tue,
Weekday::Wed,
Weekday::Thu,
Weekday::Fri,
Weekday::Sat,
Weekday::Sun,
] { // must always be below 54 for dplus in1..(400 * 366) {
assert!((base + Days::new(dplus)).weeks_from(*day) < 54)
}
}
}
#[test] fn test_leap_year() { for year in0..=MAX_YEAR { let date = NaiveDate::from_ymd_opt(year, 1, 1).unwrap(); let is_leap = year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
assert_eq!(date.leap_year(), is_leap);
assert_eq!(date.leap_year(), date.with_ordinal(366).is_some());
}
}
#[test] fn test_date_yearflags() { for (year, year_flags, _) in YEAR_FLAGS {
assert_eq!(NaiveDate::from_yo_opt(year, 1).unwrap().year_flags(), year_flags);
}
}
#[test] fn test_weekday_with_yearflags() { for (year, year_flags, first_weekday) in YEAR_FLAGS { let first_day_of_year = NaiveDate::from_yo_opt(year, 1).unwrap();
dbg!(year);
assert_eq!(first_day_of_year.year_flags(), year_flags);
assert_eq!(first_day_of_year.weekday(), first_weekday);
letmut prev = first_day_of_year.weekday(); for ordinal in2u32..=year_flags.ndays() { let date = NaiveDate::from_yo_opt(year, ordinal).unwrap(); let expected = prev.succ();
assert_eq!(date.weekday(), expected);
prev = expected;
}
}
}
#[test] fn test_isoweekdate_with_yearflags() { for (year, year_flags, _) in YEAR_FLAGS { // January 4 should be in the first week let jan4 = NaiveDate::from_ymd_opt(year, 1, 4).unwrap(); let iso_week = jan4.iso_week();
assert_eq!(jan4.year_flags(), year_flags);
assert_eq!(iso_week.week(), 1);
}
}
#[test] fn test_date_to_mdf_to_date() { for (year, year_flags, _) in YEAR_FLAGS { for ordinal in1..=year_flags.ndays() { let date = NaiveDate::from_yo_opt(year, ordinal).unwrap();
assert_eq!(date, NaiveDate::from_mdf(date.year(), date.mdf()).unwrap());
}
}
}
// Used for testing some methods with all combinations of `YearFlags`. // (year, flags, first weekday of year) const YEAR_FLAGS: [(i32, YearFlags, Weekday); 14] = [
(2006, A, Weekday::Sun),
(2005, B, Weekday::Sat),
(2010, C, Weekday::Fri),
(2009, D, Weekday::Thu),
(2003, E, Weekday::Wed),
(2002, F, Weekday::Tue),
(2001, G, Weekday::Mon),
(2012, AG, Weekday::Sun),
(2000, BA, Weekday::Sat),
(2016, CB, Weekday::Fri),
(2004, DC, Weekday::Thu),
(2020, ED, Weekday::Wed),
(2008, FE, Weekday::Tue),
(2024, GF, Weekday::Mon),
];
#[test] #[cfg(feature = "rkyv-validation")] fn test_rkyv_validation() { let date_min = NaiveDate::MIN; let bytes = rkyv::to_bytes::<_, 4>(&date_min).unwrap();
assert_eq!(rkyv::from_bytes::<NaiveDate>(&bytes).unwrap(), date_min);
let date_max = NaiveDate::MAX; let bytes = rkyv::to_bytes::<_, 4>(&date_max).unwrap();
assert_eq!(rkyv::from_bytes::<NaiveDate>(&bytes).unwrap(), date_max);
}
// MAX_YEAR-12-31 minus 0000-01-01 // = (MAX_YEAR-12-31 minus 0000-12-31) + (0000-12-31 - 0000-01-01) // = MAX_YEAR * 365 + (# of leap years from 0001 to MAX_YEAR) + 365 // = (MAX_YEAR + 1) * 365 + (# of leap years from 0001 to MAX_YEAR) const MAX_DAYS_FROM_YEAR_0: i32 =
(MAX_YEAR + 1) * 365 + MAX_YEAR / 4 - MAX_YEAR / 100 + MAX_YEAR / 400;
// MIN_YEAR-01-01 minus 0000-01-01 // = MIN_YEAR * 365 + (# of leap years from MIN_YEAR to 0000) const MIN_DAYS_FROM_YEAR_0: i32 = MIN_YEAR * 365 + MIN_YEAR / 4 - MIN_YEAR / 100 + MIN_YEAR / 400;
// only used for testing, but duplicated in naive::datetime const MAX_BITS: usize = 44;
Messung V0.5 in Prozent
¤ Diese beiden folgenden Angebotsgruppen bietet das Unternehmen0.18Angebot
(Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können 2026-08-25)
¤
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.