Skip to content

Commit

Permalink
Convert NaiveDate::from_num_days_from_ce to return Result
Browse files Browse the repository at this point in the history
  • Loading branch information
Zomtir committed Feb 28, 2024
1 parent 999582e commit bd44d85
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 44 deletions.
37 changes: 18 additions & 19 deletions src/naive/date/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<NaiveDate> {
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<NaiveDate, Error> {
// 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
Expand Down
48 changes: 24 additions & 24 deletions src/naive/date/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
2 changes: 1 addition & 1 deletion src/naive/datetime/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}
}
Expand Down

0 comments on commit bd44d85

Please sign in to comment.