use crate::time::calendars::Calendar;
use chrono::{NaiveDate, Weekday};
use serde::{Deserialize, Serialize};
#[derive(Deserialize, Serialize, Default, Debug)]
pub struct SouthKorea;
#[typetag::serde]
impl Calendar for SouthKorea {
fn is_business_day(&self, date: NaiveDate) -> bool {
let (d, w, m, y, _dd) = self.naive_date_to_dkmy(date);
if self.is_weekend(date)
|| (d == 1 && m == 1)
|| (d == 1 && m == 3)
|| (w == Weekday::Mon && (d == 2 || d == 3) && m == 3 && y > 2021)
|| (d == 5 && m == 4 && y <= 2005)
|| (d == 1 && m == 5)
|| (d == 5 && m == 5)
|| (w == Weekday::Mon && (d == 6 || d == 7) && m == 5 && y > 2013)
|| (d == 6 && m == 6)
|| (d == 17 && m == 7 && y <= 2007)
|| (d == 15 && m == 8)
|| (w == Weekday::Mon && (d == 16 || d == 17) && m == 8 && y > 2020)
|| (d == 3 && m == 10)
|| (w == Weekday::Mon && (d == 4 || d == 5) && m == 10 && y > 2020)
|| (d == 25 && m == 12)
|| (w == Weekday::Mon && (d == 26 || d == 27) && m == 12 && y > 2022)
|| ((d == 21 || d == 22 || d == 23) && m == 1 && y == 2004)
|| ((d == 8 || d == 9 || d == 10) && m == 2 && y == 2005)
|| ((d == 28 || d == 29 || d == 30) && m == 1 && y == 2006)
|| ( d == 19 && m == 2 && y == 2007)
|| ((d == 6 || d == 7 || d == 8) && m == 2 && y == 2008)
|| ((d == 25 || d == 26 || d == 27) && m == 1 && y == 2009)
|| ((d == 13 || d == 14 || d == 15) && m == 2 && y == 2010)
|| ((d == 2 || d == 3 || d == 4) && m == 2 && y == 2011)
|| ((d == 23 || d == 24) && m == 1 && y == 2012)
|| ( d == 11 && m == 2 && y == 2013)
|| ((d == 30 || d == 31) && m == 1 && y == 2014)
|| ((d == 18 || d == 19 || d == 20) && m == 2 && y == 2015)
|| ((7..=10).contains(&d) && m == 2 && y == 2016)
|| ((27..=30).contains(&d) && m == 1 && y == 2017)
|| ((d == 15 || d == 16 || d == 17) && m == 2 && y == 2018)
|| ((d == 4 || d == 5 || d == 6) && m == 2 && y == 2019)
|| ((24..=27).contains(&d) && m == 1 && y == 2020)
|| ((d == 11 || d == 12 || d == 13) && m == 2 && y == 2021)
|| (((d == 31 && m == 1) || ((d == 1 || d == 2)
&& m == 2)) && y == 2022)
|| ((d == 23 || d == 24) && m == 1 && y == 2023)
|| ((9..=12).contains(&d) && m == 2 && y == 2024)
|| ((d == 28 || d == 29 || d == 30) && m == 1 && y == 2025)
|| ((d == 16 || d == 17 || d == 18) && m == 2 && y == 2026)
|| ((d == 8 || d == 9) && m == 2 && y == 2027)
|| ((d == 26 || d == 27 || d == 28) && m == 1 && y == 2028)
|| ((d == 12 || d == 13 || d == 14) && m == 2 && y == 2029)
|| ((d == 4 || d == 5) && m == 2 && y == 2030)
|| ((d == 22 || d == 23 || d == 24) && m == 1 && y == 2031)
|| ((d == 10 || d == 11 || d == 12) && m == 2 && y == 2032)
|| (((d == 31 && m == 1) || ((d == 1|| d == 2)
&& m == 2)) && y == 2033)
|| ((d == 20 || d == 21) && m == 2 && y == 2034)
|| ((d == 7 || d == 8 || d == 9) && m == 2 && y == 2035)
|| ((d == 28 || d == 29 || d == 30) && m == 1 && y == 2036)
|| ((d == 16 || d == 17) && m == 2 && y == 2037)
|| ((d == 3 || d == 4 || d == 5) && m == 2 && y == 2038)
|| ((d == 24 || d == 25 || d == 26) && m == 1 && y == 2039)
|| ((d == 13 || d == 14) && m == 2 && y == 2040)
|| (((d == 31 && m == 1) || ((d == 1|| d == 2)
&& m == 2)) && y == 2041)
|| ((d == 21 || d == 22 || d == 23) && m == 1 && y == 2042)
|| ((d == 9 || d == 10 || d == 11) && m == 2 && y == 2043)
|| ((((d == 29|| d == 30|| d == 31) && m == 1)
|| (d == 1 && m == 2)) && y == 2044)
|| ((d == 16 || d == 17 || d == 18) && m == 2 && y == 2045)
|| ((d == 5 || d == 6 || d == 7) && m == 2 && y == 2046)
|| ((25..=28).contains(&d) && m == 1 && y == 2047)
|| ((d == 13 || d == 14 || d == 15) && m == 2 && y == 2048)
|| ((d == 1 || d == 2 || d == 3) && m == 2 && y == 2049)
|| ((d == 24 || d == 25) && m == 1 && y == 2050)
|| (d == 15 && m == 4 && y == 2004) || (d == 31 && m == 5 && y == 2006) || (d == 19 && m == 12 && y == 2007) || (d == 9 && m == 4 && y == 2008) || (d == 2 && m == 6 && y == 2010) || (d == 11 && m == 4 && y == 2012) || (d == 19 && m == 12 && y == 2012) || (d == 4 && m == 6 && y == 2014) || (d == 13 && m == 4 && y == 2016) || (d == 9 && m == 5 && y == 2017) || (d == 13 && m == 6 && y == 2018) || (d == 15 && m == 4 && y == 2020) || (d == 9 && m == 3 && y == 2022) || (d == 1 && m == 6 && y == 2022) || (d == 10 && m == 4 && y == 2024) || (d == 26 && m == 5 && y == 2004)
|| (d == 15 && m == 5 && y == 2005)
|| (d == 5 && m == 5 && y == 2006)
|| (d == 24 && m == 5 && y == 2007)
|| (d == 12 && m == 5 && y == 2008)
|| (d == 2 && m == 5 && y == 2009)
|| (d == 21 && m == 5 && y == 2010)
|| (d == 10 && m == 5 && y == 2011)
|| (d == 28 && m == 5 && y == 2012)
|| (d == 17 && m == 5 && y == 2013)
|| (d == 6 && m == 5 && y == 2014)
|| (d == 25 && m == 5 && y == 2015)
|| (d == 14 && m == 5 && y == 2016)
|| (d == 3 && m == 5 && y == 2017)
|| (d == 22 && m == 5 && y == 2018)
|| (d == 12 && m == 5 && y == 2019)
|| (d == 30 && m == 4 && y == 2020)
|| (d == 19 && m == 5 && y == 2021)
|| (d == 8 && m == 5 && y == 2022)
|| (d == 29 && m == 5 && y == 2023) || (d == 15 && m == 5 && y == 2024)
|| (d == 6 && m == 5 && y == 2025)
|| (d == 25 && m == 5 && y == 2026) || (d == 13 && m == 5 && y == 2027)
|| (d == 2 && m == 5 && y == 2028)
|| (d == 21 && m == 5 && y == 2029) || (d == 9 && m == 5 && y == 2030)
|| (d == 28 && m == 5 && y == 2031)
|| (d == 17 && m == 5 && y == 2032) || (d == 6 && m == 5 && y == 2033)
|| (d == 25 && m == 5 && y == 2034)
|| (d == 15 && m == 5 && y == 2035)
|| (d == 6 && m == 5 && y == 2036) || (d == 22 && m == 5 && y == 2037)
|| (d == 11 && m == 5 && y == 2038)
|| (d == 2 && m == 5 && y == 2039) || (d == 18 && m == 5 && y == 2040)
|| (d == 7 && m == 5 && y == 2041)
|| (d == 26 && m == 5 && y == 2042)
|| (d == 18 && m == 5 && y == 2043) || (d == 6 && m == 5 && y == 2044)
|| (d == 24 && m == 5 && y == 2045)
|| (d == 14 && m == 5 && y == 2046) || (d == 2 && m == 5 && y == 2047)
|| (d == 20 && m == 5 && y == 2048)
|| (d == 10 && m == 5 && y == 2049) || (d == 30 && m == 5 && y == 2050)
|| (d == 14 && m == 8 && y == 2015)
|| (d == 17 && m == 8 && y == 2020)
|| (d == 2 && m == 10 && y == 2023)
|| (d == 1 && m == 10 && y == 2024)
|| ((d == 27 || d == 28 || d == 29) && m == 9 && y == 2004)
|| ((d == 17 || d == 18 || d == 19) && m == 9 && y == 2005)
|| ((d == 5 || d == 6 || d == 7) && m == 10 && y == 2006)
|| ((d == 24 || d == 25 || d == 26) && m == 9 && y == 2007)
|| ((d == 13 || d == 14 || d == 15) && m == 9 && y == 2008)
|| ((d == 2 || d == 3 || d == 4) && m == 10 && y == 2009)
|| ((d == 21 || d == 22 || d == 23) && m == 9 && y == 2010)
|| ((d == 12 || d == 13) && m == 9 && y == 2011)
|| ((d == 1) && m == 10 && y == 2012)
|| ((d == 18 || d == 19 || d == 20) && m == 9 && y == 2013)
|| ((d == 8 || d == 9 || d == 10) && m == 9 && y == 2014)
|| ((d == 28 || d == 29) && m == 9 && y == 2015)
|| ((d == 14 || d == 15 || d == 16) && m == 9 && y == 2016)
|| ((3..=6).contains(&d) && m == 10 && y == 2017)
|| ((23..=26).contains(&d) && m == 9 && y == 2018)
|| ((d == 12 || d == 13 || d == 14) && m == 9 && y == 2019)
|| (((d == 30 && m == 9) || ((d == 1 || d == 2)
&& m == 10)) && y == 2020)
|| ((d == 20 || d == 21 || d == 22) && m == 9 && y == 2021)
|| ((d == 9 || d == 10 || d == 11) && m == 9 && y == 2022)
|| ((9..=12).contains(&d) && m == 9 && y == 2022)
|| ((d == 28 || d == 29 || d == 30) && m == 9 && y == 2023)
|| ((d == 16 || d == 17 || d == 18) && m == 9 && y == 2024)
|| ((d == 6 || d == 7 || d == 8) && m == 10 && y == 2025)
|| ((d == 24 || d == 25 || d == 26) && m == 9 && y == 2026)
|| ((d == 14 || d == 15 || d == 16) && m == 9 && y == 2027)
|| ((2..=5).contains(&d) && m == 10 && y == 2028)
|| ((21..=24).contains(&d) && m == 9 && y == 2029)
|| ((d == 11 || d == 12 || d == 13) && m == 9 && y == 2030)
|| (((d == 30 && m == 9) || ((d == 1 || d == 2)
&& m == 10)) && y == 2031)
|| ((d == 20 || d == 21) && m == 9 && y == 2032)
|| ((d == 7 || d == 8 || d == 9) && m == 9 && y == 2033)
|| ((d == 26 || d == 27 || d == 28) && m == 9 && y == 2034)
|| ((d == 17 || d == 18) && m == 9 && y == 2035)
|| ((3..=7).contains(&d) && m == 10 && y == 2036)
|| ((d == 23 || d == 24 || d == 25) && m == 9 && y == 2037)
|| ((d == 13 || d == 14 || d == 15) && m == 9 && y == 2038)
|| ((d == 3 || d == 4 || d == 5) && m == 10 && y == 2039)
|| ((d == 20 || d == 21 || d == 22) && m == 9 && y == 2040)
|| ((d == 9 || d == 10 || d == 11) && m == 9 && y == 2041)
|| ((d == 29 || d == 30) && m == 9 && y == 2042)
|| ((d == 16 || d == 17 || d == 18) && m == 9 && y == 2043)
|| ((d == 4 || d == 5 || d == 6) && m == 10 && y == 2044)
|| ((d == 25 || d == 26 || d == 27) && m == 9 && y == 2045)
|| ((14..=17).contains(&d) && m == 9 && y == 2046)
|| ((d == 4 || d == 5 || d == 7) && m == 10 && y == 2047)
|| ((d == 21 || d == 22 || d == 23) && m == 9 && y == 2048)
|| ((10..=13).contains(&d) && m == 9 && y == 2049)
|| ((((d == 29|| d == 30) && m == 9)
|| (d == 1 && m == 10)) && y == 2050)
|| (d == 9 && m == 10 && y >= 2013)
|| (w == Weekday::Mon && (d == 10 || d == 11) && m == 10 && y > 2020)
{
return false;
}
true
}
}
#[cfg(test)]
mod tests {
use super::SouthKorea;
use crate::time::calendars::Calendar;
use chrono::{Duration, NaiveDate};
#[test]
fn test_south_korea_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, false, false, 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, false, 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, false, 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, false, 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, false, 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, false, 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, false, true, 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::try_days(n as i64).unwrap();
let expected = expected_results_for_2023[n as usize];
assert_eq!(SouthKorea.is_business_day(target_date), expected);
}
}
}