Skip to content

Commit

Permalink
Add NaiveDate::leap_year
Browse files Browse the repository at this point in the history
  • Loading branch information
pitdicker committed Sep 6, 2023
1 parent 84334df commit c693554
Showing 1 changed file with 25 additions and 0 deletions.
25 changes: 25 additions & 0 deletions src/naive/date.rs
Expand Up @@ -1412,6 +1412,21 @@ impl NaiveDate {
NaiveWeek { date: *self, start }
}

/// Returns `true` if this is a leap year.
///
/// ```
/// # use chrono::NaiveDate;
/// assert_eq!(NaiveDate::from_ymd_opt(2000, 1, 1).unwrap().leap_year(), true);
/// assert_eq!(NaiveDate::from_ymd_opt(2001, 1, 1).unwrap().leap_year(), false);
/// assert_eq!(NaiveDate::from_ymd_opt(2002, 1, 1).unwrap().leap_year(), false);
/// assert_eq!(NaiveDate::from_ymd_opt(2003, 1, 1).unwrap().leap_year(), false);
/// assert_eq!(NaiveDate::from_ymd_opt(2004, 1, 1).unwrap().leap_year(), true);
/// assert_eq!(NaiveDate::from_ymd_opt(2100, 1, 1).unwrap().leap_year(), false);
/// ```
pub const fn leap_year(&self) -> bool {
self.ymdf & (0b1000) == 0
}

// This duplicates `Datelike::year()`, because trait methods can't be const yet.
#[inline]
const fn year(&self) -> i32 {
Expand Down Expand Up @@ -3205,6 +3220,16 @@ mod tests {
assert!(dt.with_ordinal0(4294967295).is_none());
}

#[test]
fn test_leap_year() {
for year in 0..=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());
}
}

// MAX_YEAR-12-31 minus 0000-01-01
// = ((MAX_YEAR+1)-01-01 minus 0001-01-01) + (0001-01-01 minus 0000-01-01) - 1 day
// = ((MAX_YEAR+1)-01-01 minus 0001-01-01) + 365 days
Expand Down

0 comments on commit c693554

Please sign in to comment.