diff --git a/src/naive/date/mod.rs b/src/naive/date/mod.rs index 613ab4254c..ae627300ac 100644 --- a/src/naive/date/mod.rs +++ b/src/naive/date/mod.rs @@ -296,35 +296,34 @@ impl NaiveDate { /// /// # Errors /// - /// Returns `None` if the date is out of range. + /// Returns [`Error::OutOfRange`] if the date is out of range. /// /// # Example /// /// ``` - /// use chrono::NaiveDate; - /// + /// # use chrono::{Error, NaiveDate}; /// let from_ndays = NaiveDate::from_num_days_from_ce; - /// let from_ymd = |y, m, d| NaiveDate::from_ymd(y, m, d).unwrap(); + /// let from_ymd = NaiveDate::from_ymd; /// - /// assert_eq!(from_ndays(730_000), Some(from_ymd(1999, 9, 3))); - /// assert_eq!(from_ndays(1), Some(from_ymd(1, 1, 1))); - /// assert_eq!(from_ndays(0), Some(from_ymd(0, 12, 31))); - /// assert_eq!(from_ndays(-1), Some(from_ymd(0, 12, 30))); - /// assert_eq!(from_ndays(100_000_000), None); - /// assert_eq!(from_ndays(-100_000_000), None); - /// ``` - #[must_use] - pub const fn from_num_days_from_ce(days: i32) -> Option { - let days = try_opt!(days.checked_add(365)); // make December 31, 1 BCE equal to day 0 + /// assert_eq!(from_ndays(730_000), from_ymd(1999, 9, 3)); + /// assert_eq!(from_ndays(1), from_ymd(1, 1, 1)); + /// assert_eq!(from_ndays(0), from_ymd(0, 12, 31)); + /// assert_eq!(from_ndays(-1), from_ymd(0, 12, 30)); + /// assert_eq!(from_ndays(100_000_000), Err(Error::OutOfRange)); + /// assert_eq!(from_ndays(-100_000_000), Err(Error::OutOfRange)); + /// # Ok::<(), Error>(()) + /// ``` + pub const fn from_num_days_from_ce(days: i32) -> Result { + // make December 31, 1 BCE equal to day 0 + let days = match days.checked_add(365) { + Some(d) => d, + None => return Err(Error::OutOfRange), + }; let year_div_400 = days.div_euclid(146_097); let cycle = days.rem_euclid(146_097); let (year_mod_400, ordinal) = cycle_to_yo(cycle as u32); let flags = YearFlags::from_year_mod_400(year_mod_400 as i32); - ok!(NaiveDate::from_ordinal_and_flags( - year_div_400 * 400 + year_mod_400 as i32, - ordinal, - flags - )) + NaiveDate::from_ordinal_and_flags(year_div_400 * 400 + year_mod_400 as i32, ordinal, flags) } /// Makes a new `NaiveDate` by counting the number of occurrences of a particular day-of-week diff --git a/src/naive/date/tests.rs b/src/naive/date/tests.rs index 79c8de267e..2d23eec2ca 100644 --- a/src/naive/date/tests.rs +++ b/src/naive/date/tests.rs @@ -268,35 +268,35 @@ fn test_date_from_isoywd_and_iso_week() { #[test] fn test_date_from_num_days_from_ce() { let from_ndays_from_ce = NaiveDate::from_num_days_from_ce; - assert_eq!(from_ndays_from_ce(1), Some(NaiveDate::from_ymd(1, 1, 1).unwrap())); - assert_eq!(from_ndays_from_ce(2), Some(NaiveDate::from_ymd(1, 1, 2).unwrap())); - assert_eq!(from_ndays_from_ce(31), Some(NaiveDate::from_ymd(1, 1, 31).unwrap())); - assert_eq!(from_ndays_from_ce(32), Some(NaiveDate::from_ymd(1, 2, 1).unwrap())); - assert_eq!(from_ndays_from_ce(59), Some(NaiveDate::from_ymd(1, 2, 28).unwrap())); - assert_eq!(from_ndays_from_ce(60), Some(NaiveDate::from_ymd(1, 3, 1).unwrap())); - assert_eq!(from_ndays_from_ce(365), Some(NaiveDate::from_ymd(1, 12, 31).unwrap())); - assert_eq!(from_ndays_from_ce(365 + 1), Some(NaiveDate::from_ymd(2, 1, 1).unwrap())); - assert_eq!(from_ndays_from_ce(365 * 2 + 1), Some(NaiveDate::from_ymd(3, 1, 1).unwrap())); - assert_eq!(from_ndays_from_ce(365 * 3 + 1), Some(NaiveDate::from_ymd(4, 1, 1).unwrap())); - assert_eq!(from_ndays_from_ce(365 * 4 + 2), Some(NaiveDate::from_ymd(5, 1, 1).unwrap())); - assert_eq!(from_ndays_from_ce(146097 + 1), Some(NaiveDate::from_ymd(401, 1, 1).unwrap())); - assert_eq!(from_ndays_from_ce(146097 * 5 + 1), Some(NaiveDate::from_ymd(2001, 1, 1).unwrap())); - assert_eq!(from_ndays_from_ce(719163), Some(NaiveDate::from_ymd(1970, 1, 1).unwrap())); - assert_eq!(from_ndays_from_ce(0), Some(NaiveDate::from_ymd(0, 12, 31).unwrap())); // 1 BCE - assert_eq!(from_ndays_from_ce(-365), Some(NaiveDate::from_ymd(0, 1, 1).unwrap())); - assert_eq!(from_ndays_from_ce(-366), Some(NaiveDate::from_ymd(-1, 12, 31).unwrap())); // 2 BCE + assert_eq!(from_ndays_from_ce(1), NaiveDate::from_ymd(1, 1, 1)); + assert_eq!(from_ndays_from_ce(2), NaiveDate::from_ymd(1, 1, 2)); + assert_eq!(from_ndays_from_ce(31), NaiveDate::from_ymd(1, 1, 31)); + assert_eq!(from_ndays_from_ce(32), NaiveDate::from_ymd(1, 2, 1)); + assert_eq!(from_ndays_from_ce(59), NaiveDate::from_ymd(1, 2, 28)); + assert_eq!(from_ndays_from_ce(60), NaiveDate::from_ymd(1, 3, 1)); + assert_eq!(from_ndays_from_ce(365), NaiveDate::from_ymd(1, 12, 31)); + assert_eq!(from_ndays_from_ce(365 + 1), NaiveDate::from_ymd(2, 1, 1)); + assert_eq!(from_ndays_from_ce(365 * 2 + 1), NaiveDate::from_ymd(3, 1, 1)); + assert_eq!(from_ndays_from_ce(365 * 3 + 1), NaiveDate::from_ymd(4, 1, 1)); + assert_eq!(from_ndays_from_ce(365 * 4 + 2), NaiveDate::from_ymd(5, 1, 1)); + assert_eq!(from_ndays_from_ce(146097 + 1), NaiveDate::from_ymd(401, 1, 1)); + assert_eq!(from_ndays_from_ce(146097 * 5 + 1), NaiveDate::from_ymd(2001, 1, 1)); + assert_eq!(from_ndays_from_ce(719163), NaiveDate::from_ymd(1970, 1, 1)); + assert_eq!(from_ndays_from_ce(0), NaiveDate::from_ymd(0, 12, 31)); // 1 BCE + assert_eq!(from_ndays_from_ce(-365), NaiveDate::from_ymd(0, 1, 1)); + assert_eq!(from_ndays_from_ce(-366), NaiveDate::from_ymd(-1, 12, 31)); // 2 BCE for days in (-9999..10001).map(|x| x * 100) { - assert_eq!(from_ndays_from_ce(days).map(|d| d.num_days_from_ce()), Some(days)); + assert_eq!(from_ndays_from_ce(days).map(|d| d.num_days_from_ce()), Ok(days)); } - assert_eq!(from_ndays_from_ce(NaiveDate::MIN.num_days_from_ce()), Some(NaiveDate::MIN)); - assert_eq!(from_ndays_from_ce(NaiveDate::MIN.num_days_from_ce() - 1), None); - assert_eq!(from_ndays_from_ce(NaiveDate::MAX.num_days_from_ce()), Some(NaiveDate::MAX)); - assert_eq!(from_ndays_from_ce(NaiveDate::MAX.num_days_from_ce() + 1), None); + assert_eq!(from_ndays_from_ce(NaiveDate::MIN.num_days_from_ce()), Ok(NaiveDate::MIN)); + assert_eq!(from_ndays_from_ce(NaiveDate::MIN.num_days_from_ce() - 1), Err(Error::OutOfRange)); + assert_eq!(from_ndays_from_ce(NaiveDate::MAX.num_days_from_ce()), Ok(NaiveDate::MAX)); + assert_eq!(from_ndays_from_ce(NaiveDate::MAX.num_days_from_ce() + 1), Err(Error::OutOfRange)); - assert_eq!(from_ndays_from_ce(i32::MIN), None); - assert_eq!(from_ndays_from_ce(i32::MAX), None); + assert_eq!(from_ndays_from_ce(i32::MIN), Err(Error::OutOfRange)); + assert_eq!(from_ndays_from_ce(i32::MAX), Err(Error::OutOfRange)); } #[test] diff --git a/src/naive/datetime/mod.rs b/src/naive/datetime/mod.rs index a9c42c3400..69e5e70197 100644 --- a/src/naive/datetime/mod.rs +++ b/src/naive/datetime/mod.rs @@ -238,7 +238,7 @@ impl NaiveDateTime { let date = NaiveDate::from_num_days_from_ce(try_opt!((days as i32).checked_add(719_163))); let time = NaiveTime::from_num_seconds_from_midnight(secs as u32, nsecs); match (date, time) { - (Some(date), Ok(time)) => Some(NaiveDateTime { date, time }), + (Ok(date), Ok(time)) => Some(NaiveDateTime { date, time }), (_, _) => None, } }