liturgical/western/
advent.rs

1use super::error::WesternDateError;
2use chrono::naive::NaiveDate;
3use chrono::prelude::*;
4use chrono::Duration;
5
6/// calculate the date of Advent Sunday: the fourth Sunday before Christmas Day,
7/// and the beginning of the Western liturgical calendar
8pub fn date(year: i32) -> Result<NaiveDate, WesternDateError> {
9    if year < 1583 {
10        return Err(WesternDateError::InvalidPrior1583);
11    }
12    let christmas = NaiveDate::from_ymd(year, 12, 25);
13    // the number of days we need to seek back for the Sunday prior to Christmas Day
14    // (if Christmas Day is on a Sunday, this is 7)
15    let sunday_offset = christmas.weekday() as i64 + 1;
16    println!("{}", sunday_offset);
17    let advent_sunday = christmas + Duration::days(-21 - sunday_offset);
18
19    return Ok(advent_sunday);
20}
21
22#[cfg(test)]
23mod tests {
24    #[test]
25    fn advent_valid_dates() {
26        use super::date;
27        use chrono::naive::NaiveDate;
28        fn td(y: i32, m: u32, d: u32) {
29            assert_eq!(date(y), Ok(NaiveDate::from_ymd(y, m, d)));
30        }
31        td(2020, 11, 29);
32        td(2022, 11, 27);
33        td(2023, 12, 3);
34    }
35
36    #[test]
37    fn fail_before_gregory() {
38        use super::super::error::WesternDateError;
39        use super::date;
40        assert_eq!(date(1582), Err(WesternDateError::InvalidPrior1583));
41    }
42}