use crate::time::calendars::Calendar;
use chrono::{NaiveDate, Weekday};
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Default, Debug)]
pub struct Iceland;
#[typetag::serialize]
impl Calendar for Iceland {
fn is_business_day(&self, date: NaiveDate) -> bool {
let (d, w, m, y, dd) = self.naive_date_to_dkmy(date);
let em = self.easter_monday(y);
if self.is_weekend(date)
|| (d == 1 && m == 1)
|| (dd == em-4)
|| (dd == em-3)
|| (dd == em)
|| ((19..=25).contains(&d) && w == Weekday::Thu && m == 4)
|| (dd == em+38)
|| (dd == em+49)
|| (d == 1 && m == 5)
|| (d == 17 && m == 6)
|| (d <= 7 && w == Weekday::Mon && m == 8)
|| (d == 25 && m == 12)
|| (d == 26 && m == 12)
{
return false;
}
true
}
}
#[cfg(test)]
mod tests {
use super::Iceland;
use crate::time::calendars::Calendar;
use chrono::{Duration, NaiveDate};
#[test]
fn test_iceland_holiday() {
let expected_results_for_2023 = vec![
false, true, true, true, true, true, false, false, true, true, true, true, true, false,
false, true, true, true, true, true, false, false, true, true, true, true, true, false,
false, true, true, true, true, true, false, false, true, true, true, true, true, false,
false, true, true, true, true, true, false, false, true, true, true, true, true, false,
false, true, true, true, true, true, false, false, true, true, true, true, true, false,
false, true, true, true, true, true, false, false, true, true, true, true, true, false,
false, true, true, true, true, true, false, false, true, true, true, false, false,
false, false, false, true, true, true, true, false, false, true, true, true, false,
true, false, false, true, true, true, true, true, false, false, false, true, true,
true, true, false, false, true, true, true, true, true, false, false, true, true, true,
false, true, false, false, true, true, true, true, true, false, false, false, true,
true, true, true, false, false, true, true, true, true, true, false, false, true, true,
true, true, true, false, false, true, true, true, true, true, false, false, true, true,
true, true, true, false, false, true, true, true, true, true, false, false, true, true,
true, true, true, false, false, true, true, true, true, true, false, false, true, true,
true, true, true, false, false, true, true, true, true, true, false, false, false,
true, true, true, true, false, false, true, true, true, true, true, false, false, true,
true, true, true, true, false, false, true, true, true, true, true, false, false, true,
true, true, true, true, false, false, true, true, true, true, true, false, false, true,
true, true, true, true, false, false, true, true, true, true, true, false, false, true,
true, true, true, true, false, false, true, true, true, true, true, false, false, true,
true, true, true, true, false, false, true, true, true, true, true, false, false, true,
true, true, true, true, false, false, true, true, true, true, true, false, false, true,
true, true, true, true, false, false, true, true, true, true, true, false, false, true,
true, true, true, true, false, false, true, true, true, true, true, false, false, true,
true, true, true, true, false, false, true, true, true, true, true, false, false,
false, false, true, true, true, false, false,
];
let first_date = NaiveDate::from_ymd_opt(2023, 1, 1).unwrap();
for n in 0i32..365 {
let target_date = first_date + Duration::days(n as i64);
let expected = expected_results_for_2023[n as usize];
assert_eq!(Iceland.is_business_day(target_date), expected);
}
}
}