diff --git a/src/time/calendars/denmark.rs b/src/time/calendars/denmark.rs index 3d439690..a38eded6 100644 --- a/src/time/calendars/denmark.rs +++ b/src/time/calendars/denmark.rs @@ -27,7 +27,7 @@ impl Calendar for Denmark { } /// Denmark holidays: - /// - Maunday Thursday + /// - Maundy Thursday /// - Good Friday /// - Easter Monday /// - General Prayer Day diff --git a/src/time/calendars/hungary.rs b/src/time/calendars/hungary.rs index fac1e036..26361969 100644 --- a/src/time/calendars/hungary.rs +++ b/src/time/calendars/hungary.rs @@ -96,8 +96,8 @@ mod test_hungary { let labour_day = datetime!(2024-05-01 12:00:00 UTC); let national_holiday = datetime!(2024-08-20 12:00:00 UTC); let revolution_1956_day = datetime!(2024-10-23 12:00:00 UTC); - let christmas = datetime!(2023-12-25 12:00:00 UTC); - let second_christmas_day = datetime!(2023-12-26 12:00:00 UTC); + let christmas = datetime!(2024-12-25 12:00:00 UTC); + let second_christmas_day = datetime!(2024-12-26 12:00:00 UTC); assert!(!calendar.is_business_day(new_years_day)); assert!(!calendar.is_business_day(revolution_1848_day)); diff --git a/src/time/calendars/iceland.rs b/src/time/calendars/iceland.rs index a087594c..e8004a24 100644 --- a/src/time/calendars/iceland.rs +++ b/src/time/calendars/iceland.rs @@ -10,19 +10,56 @@ use crate::time::Calendar; use time::{Month, OffsetDateTime, Weekday}; -/// Czech Republic calendar. -pub struct CzechRepublic; +/// Iceland calendar. +pub struct Iceland; -impl Calendar for CzechRepublic { +impl Calendar for Iceland { fn name(&self) -> &'static str { - "" + "Iceland" + } + + fn country_code(&self) -> crate::iso::ISO_3166 { + crate::iso::ICELAND + } + + fn market_identifier_code(&self) -> crate::iso::ISO_10383 { + crate::iso::XICE } fn is_business_day(&self, date: OffsetDateTime) -> bool { let (w, d, m, y, dd) = self.unpack_date(date); let em = Self::easter_monday(y as usize, false); - if Self::is_weekend(date) { + if Self::is_weekend(date) + // New Year's Day + || (d == 1 && m == Month::January) + // Maundy Thursday + || (dd == em - 4) + // Good Friday + || (dd == em - 3) + // Easter Monday + || (dd == em) + // First Day of Summer (first Thursday after 18th of April) + || (w == Weekday::Thursday && (19..=25).contains(&d) && m == Month::April) + // Labor Day + || (d == 1 && m == Month::May) + // Ascension Day + || (dd == em + 38) + // Whit Monday + || (dd == em + 49) + // Icelandic Republic Day + || (d == 17 && m == Month::June) + // Commerce Day (first Monday of August) + || (d <= 7 && w == Weekday::Monday && m == Month::August) + // Christmas Eve + || (d == 24 && m == Month::December) + // Christmas + || (d == 25 && m == Month::December) + // Boxing Day + || (d == 26 && m == Month::December) + // New Year's Eve + || (d == 31 && m == Month::December) + { return false; } @@ -35,4 +72,62 @@ impl Calendar for CzechRepublic { // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #[cfg(test)] -mod tests {} +mod test_iceland { + use super::*; + use time::macros::datetime; + + // Test to verify the name() method. + #[test] + fn test_name() { + let calendar = Iceland; + assert_eq!(calendar.name(), "Iceland"); + } + + // Test to verify if weekends are not considered business days. + #[test] + fn test_is_weekend() { + let calendar = Iceland; + let sat = datetime!(2024-01-13 12:00:00 UTC); + let sun = datetime!(2024-01-14 12:00:00 UTC); + assert!(!calendar.is_business_day(sat)); + assert!(!calendar.is_business_day(sun)); + } + + // Test to verify if the is_business_day() method properly accounts for public holidays. + #[test] + fn test_is_public_holiday() { + let calendar = Iceland; + let new_years_day = datetime!(2024-01-01 12:00:00 UTC); + let maudy_thursday = datetime!(2024-03-28 12:00:00 UTC); + let first_day_of_summer = datetime!(2024-04-25 12:00:00 UTC); + let labour_day = datetime!(2024-05-01 12:00:00 UTC); + let ascension_day = datetime!(2024-05-09 12:00:00 UTC); + let independence_day = datetime!(2024-06-17 12:00:00 UTC); + let commerce_day = datetime!(2024-08-05 12:00:00 UTC); + let christmas = datetime!(2024-12-25 12:00:00 UTC); + let new_years_eve = datetime!(2024-12-31 12:00:00 UTC); + + assert!(!calendar.is_business_day(new_years_day)); + assert!(!calendar.is_business_day(maudy_thursday)); + assert!(!calendar.is_business_day(first_day_of_summer)); + assert!(!calendar.is_business_day(labour_day)); + assert!(!calendar.is_business_day(ascension_day)); + assert!(!calendar.is_business_day(independence_day)); + assert!(!calendar.is_business_day(commerce_day)); + assert!(!calendar.is_business_day(christmas)); + assert!(!calendar.is_business_day(new_years_eve)); + } + + // Test to verify if the is_business_day() method properly accounts for regular business days. + #[test] + fn test_is_regular_business_day() { + let calendar = Iceland; + let regular_day1 = datetime!(2024-01-17 12:00:00 UTC); + let regular_day2 = datetime!(2024-07-08 12:00:00 UTC); + let regular_day3 = datetime!(2024-11-18 12:00:00 UTC); + + assert!(calendar.is_business_day(regular_day1)); + assert!(calendar.is_business_day(regular_day2)); + assert!(calendar.is_business_day(regular_day3)); + } +} diff --git a/src/time/calendars/india.rs b/src/time/calendars/india.rs index a087594c..51204544 100644 --- a/src/time/calendars/india.rs +++ b/src/time/calendars/india.rs @@ -8,21 +8,62 @@ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ use crate::time::Calendar; -use time::{Month, OffsetDateTime, Weekday}; +use time::{Month, OffsetDateTime}; -/// Czech Republic calendar. -pub struct CzechRepublic; +/// India calendar. +pub struct India; -impl Calendar for CzechRepublic { +impl Calendar for India { fn name(&self) -> &'static str { - "" + "India" + } + + fn country_code(&self) -> crate::iso::ISO_3166 { + crate::iso::INDIA + } + + fn market_identifier_code(&self) -> crate::iso::ISO_10383 { + crate::iso::XBOM } fn is_business_day(&self, date: OffsetDateTime) -> bool { - let (w, d, m, y, dd) = self.unpack_date(date); + let (_, d, m, y, dd) = self.unpack_date(date); let em = Self::easter_monday(y as usize, false); - if Self::is_weekend(date) { + if Self::is_weekend(date) + // Republic Day + || (d == 26 && m == Month::January) + // Mahashivratri + || is_mahashivratri(y, d, m) + // Holi + || is_holi(y, d, m) + // Good Friday + || (dd == em - 3) + // Eid-ul-Fitar + || is_eid_ul_fitar(y,d,m) + // Rama Navami + || is_rama_navami(y,d,m) + // Mahavir Jayanti + || is_mahavir_jayanti(y,d,m) + // Maharashtra Day + || (d == 1 && m == Month::May) + // Bakri Id + || is_bakri_id(y,d,m) + // Muharram + || is_muharram(y,d,m) + // Independence Day + || (d == 15 && m == Month::August) + // Gandhi Jayanti + || (d == 2 && m == Month::October) + // Dussehra + || is_dussehra(y,d,m) + // Diwali + || is_diwali(y,d,m) + // Gurunanak Jayanti + || is_gurunanak_jayanti(y,d,m) + // Christmas + || (d == 25 && m == Month::December) + { return false; } @@ -30,9 +71,433 @@ impl Calendar for CzechRepublic { } } +#[allow(clippy::unnested_or_patterns)] +fn is_mahashivratri(year: i32, day: u8, month: Month) -> bool { + use Month::{February, March}; + matches!( + (year, day, month), + (2000, 4, March) + | (2001, 21, February) + | (2002, 12, March) + | (2003, 1, March) + | (2004, 18, February) + | (2005, 8, March) + | (2006, 26, February) + | (2007, 16, February) + | (2008, 6, March) + | (2009, 23, February) + | (2010, 12, February) + | (2011, 2, March) + | (2012, 20, February) + | (2013, 10, March) + | (2014, 27, February) + | (2015, 17, February) + | (2016, 7, March) + | (2017, 24, February) + | (2018, 13, February) + | (2019, 4, March) + | (2020, 21, February) + | (2021, 11, March) + | (2022, 1, March) + | (2023, 18, February) + | (2024, 8, March) + | (2025, 26, February) + | (2026, 15, February) + | (2027, 6, March) + | (2028, 23, February) + | (2029, 11, February) + ) +} + +#[allow(clippy::unnested_or_patterns)] +fn is_holi(year: i32, day: u8, month: Month) -> bool { + use Month::March; + matches!( + (year, day, month), + (2000, 20, March) + | (2001, 10, March) + | (2002, 29, March) + | (2003, 18, March) + | (2004, 7, March) + | (2005, 26, March) + | (2006, 15, March) + | (2007, 4, March) + | (2008, 22, March) + | (2009, 11, March) + | (2010, 1, March) + | (2011, 20, March) + | (2012, 8, March) + | (2013, 27, March) + | (2014, 17, March) + | (2015, 6, March) + | (2016, 24, March) + | (2017, 13, March) + | (2018, 2, March) + | (2019, 21, March) + | (2020, 10, March) + | (2021, 29, March) + | (2022, 18, March) + | (2023, 8, March) + | (2024, 25, March) + | (2025, 14, March) + | (2026, 4, March) + | (2027, 22, March) + | (2028, 11, March) + | (2029, 1, March) + ) +} + +#[allow(clippy::unnested_or_patterns)] +fn is_eid_ul_fitar(year: i32, day: u8, month: Month) -> bool { + matches!( + (year, day, month), + (2000, 8, Month::January) + | (2000, 28, Month::December) + | (2001, 17, Month::December) + | (2002, 6, Month::December) + | (2003, 26, Month::November) + | (2004, 14, Month::November) + | (2005, 4, Month::November) + | (2006, 24, Month::October) + | (2007, 13, Month::October) + | (2008, 2, Month::October) + | (2009, 21, Month::September) + | (2010, 10, Month::September) + | (2011, 31, Month::August) + | (2012, 20, Month::August) + | (2013, 9, Month::August) + | (2014, 29, Month::July) + | (2015, 19, Month::July) + | (2016, 6, Month::July) + | (2017, 26, Month::June) + | (2018, 15, Month::June) + | (2019, 5, Month::June) + | (2020, 25, Month::May) + | (2021, 14, Month::May) + | (2022, 3, Month::May) + | (2023, 22, Month::April) + | (2024, 11, Month::April) + | (2025, 31, Month::March) + | (2026, 21, Month::March) + | (2027, 10, Month::March) + | (2028, 27, Month::February) + | (2029, 15, Month::February) + ) +} + +#[allow(clippy::unnested_or_patterns)] +fn is_rama_navami(year: i32, day: u8, month: Month) -> bool { + use Month::{April, March}; + matches!( + (year, day, month), + (2000, 12, April) + | (2001, 2, April) + | (2002, 21, April) + | (2003, 11, April) + | (2004, 30, March) + | (2005, 18, April) + | (2006, 6, April) + | (2007, 26, March) + | (2008, 13, April) + | (2009, 3, April) + | (2010, 24, March) + | (2011, 12, April) + | (2012, 1, April) + | (2013, 19, April) + | (2014, 8, April) + | (2015, 28, March) + | (2016, 15, April) + | (2017, 4, April) + | (2018, 25, March) + | (2019, 13, April) + | (2020, 2, April) + | (2021, 21, April) + | (2022, 10, April) + | (2023, 30, March) + | (2024, 17, April) + | (2025, 6, April) + | (2026, 26, March) + | (2027, 15, April) + | (2028, 3, April) + | (2029, 22, April) + ) +} + +#[allow(clippy::unnested_or_patterns)] +fn is_mahavir_jayanti(year: i32, day: u8, month: Month) -> bool { + use Month::{April, March}; + matches!( + (year, day, month), + (2005, 22, April) + | (2006, 11, April) + | (2007, 31, March) + | (2008, 18, April) + | (2009, 7, April) + | (2010, 28, April) + | (2011, 16, April) + | (2012, 5, April) + | (2013, 24, April) + | (2014, 13, April) + | (2015, 2, April) + | (2016, 20, April) + | (2017, 9, April) + | (2018, 29, March) + | (2019, 17, April) + | (2020, 6, April) + | (2021, 25, April) + | (2022, 14, April) + | (2023, 4, April) + | (2024, 21, April) + | (2025, 10, April) + ) +} + +#[allow(clippy::unnested_or_patterns)] +fn is_bakri_id(year: i32, day: u8, month: Month) -> bool { + matches!( + (year, day, month), + (2000, 16, Month::March) + | (2001, 6, Month::March) + | (2002, 23, Month::February) + | (2003, 12, Month::February) + | (2004, 2, Month::February) + | (2005, 21, Month::January) + | (2006, 11, Month::January) + | (2007, 20, Month::December) + | (2008, 9, Month::December) + | (2009, 28, Month::November) + | (2010, 17, Month::November) + | (2011, 7, Month::November) + | (2012, 27, Month::October) + | (2013, 16, Month::October) + | (2014, 6, Month::October) + | (2015, 25, Month::September) + | (2016, 13, Month::September) + | (2017, 2, Month::September) + | (2018, 22, Month::August) + | (2019, 12, Month::August) + | (2020, 1, Month::August) + | (2021, 21, Month::July) + | (2022, 10, Month::July) + | (2023, 29, Month::June) + | (2024, 17, Month::June) + | (2025, 7, Month::June) + | (2026, 28, Month::May) + | (2027, 17, Month::May) + | (2028, 6, Month::May) + | (2029, 25, Month::April) + ) +} + +#[allow(clippy::unnested_or_patterns)] +fn is_muharram(year: i32, day: u8, month: Month) -> bool { + matches!( + (year, day, month), + (2007, 30, Month::January) + | (2009, 28, Month::December) + | (2010, 17, Month::December) + | (2011, 6, Month::December) + | (2012, 25, Month::November) + | (2013, 14, Month::November) + | (2014, 4, Month::November) + | (2015, 24, Month::October) + | (2016, 12, Month::October) + | (2017, 1, Month::October) + | (2018, 21, Month::September) + | (2019, 10, Month::September) + | (2020, 30, Month::August) + | (2021, 20, Month::August) + | (2022, 9, Month::August) + | (2023, 29, Month::July) + | (2024, 17, Month::July) + | (2025, 6, Month::July) + | (2026, 26, Month::June) + | (2027, 16, Month::June) + | (2028, 4, Month::June) + | (2029, 25, Month::May) + ) +} + +#[allow(clippy::unnested_or_patterns)] +fn is_dussehra(year: i32, day: u8, month: Month) -> bool { + use Month::{October, September}; + matches!( + (year, day, month), + (2000, 7, October) + | (2001, 26, October) + | (2002, 15, October) + | (2003, 5, October) + | (2004, 22, October) + | (2005, 12, October) + | (2006, 2, October) + | (2007, 21, October) + | (2008, 9, October) + | (2009, 28, September) + | (2010, 17, October) + | (2011, 6, October) + | (2012, 24, October) + | (2013, 13, October) + | (2014, 3, October) + | (2015, 22, October) + | (2016, 11, October) + | (2017, 30, September) + | (2018, 19, October) + | (2019, 8, October) + | (2020, 25, October) + | (2021, 15, October) + | (2022, 5, October) + | (2023, 24, October) + | (2024, 12, October) + | (2025, 2, October) + | (2026, 20, October) + | (2027, 9, October) + | (2028, 27, September) + | (2029, 16, October) + ) +} + +#[allow(clippy::unnested_or_patterns)] +fn is_diwali(year: i32, day: u8, month: Month) -> bool { + use Month::{November, October}; + matches!( + (year, day, month), + (2000, 26, October) + | (2001, 14, November) + | (2002, 4, November) + | (2003, 25, October) + | (2004, 12, November) + | (2005, 1, November) + | (2006, 21, October) + | (2007, 9, November) + | (2008, 28, October) + | (2009, 17, October) + | (2010, 5, November) + | (2011, 26, October) + | (2012, 13, November) + | (2013, 3, November) + | (2014, 23, October) + | (2015, 11, November) + | (2016, 30, October) + | (2017, 19, October) + | (2018, 7, November) + | (2019, 27, October) + | (2020, 14, November) + | (2021, 4, November) + | (2022, 24, October) + | (2023, 12, November) + | (2024, 31, October) + | (2025, 20, October) + | (2026, 8, November) + | (2027, 29, October) + | (2028, 17, October) + | (2029, 5, November) + ) +} + +#[allow(clippy::unnested_or_patterns)] +fn is_gurunanak_jayanti(year: i32, day: u8, month: Month) -> bool { + use Month::November; + matches!( + (year, day, month), + (2005, 15, November) + | (2006, 5, November) + | (2007, 24, November) + | (2008, 13, November) + | (2009, 2, November) + | (2010, 21, November) + | (2011, 10, November) + | (2012, 28, November) + | (2013, 17, November) + | (2014, 6, November) + | (2015, 25, November) + | (2016, 14, November) + | (2017, 4, November) + | (2018, 23, November) + | (2019, 12, November) + | (2020, 30, November) + | (2021, 19, November) + | (2022, 8, November) + | (2023, 27, November) + | (2024, 15, November) + | (2025, 5, November) + ) +} + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // UNIT TESTS // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #[cfg(test)] -mod tests {} +mod test_india { + use super::*; + use time::macros::datetime; + + // Test to verify the name() method. + #[test] + fn test_name() { + let calendar = India; + assert_eq!(calendar.name(), "India"); + } + + // Test to verify if weekends are not considered business days. + #[test] + fn test_is_weekend() { + let calendar = India; + let sat = datetime!(2024-03-09 12:00:00 UTC); + let sun = datetime!(2024-03-10 12:00:00 UTC); + assert!(!calendar.is_business_day(sat)); + assert!(!calendar.is_business_day(sun)); + } + + // Test to verify if the is_business_day() method properly accounts for public holidays. + #[test] + fn test_is_public_holiday() { + let calendar = India; + let republic_day = datetime!(2024-01-26 12:00:00 UTC); + let mahashivratri = datetime!(2024-03-08 12:00:00 UTC); + let holi = datetime!(2024-03-25 12:00:00 UTC); + let good_friday = datetime!(2024-03-29 12:00:00 UTC); + let eid_ul_fitar = datetime!(2024-04-11 12:00:00 UTC); + let rama_navami = datetime!(2024-04-17 12:00:00 UTC); + let mahavir_jayanti = datetime!(2024-04-21 12:00:00 UTC); + let maharashtra_day = datetime!(2024-05-01 12:00:00 UTC); + let bakri_id = datetime!(2024-06-17 12:00:00 UTC); + let muharram = datetime!(2024-07-17 12:00:00 UTC); + let independence_day = datetime!(2024-08-15 12:00:00 UTC); + let gandhi_jayanti = datetime!(2024-10-02 12:00:00 UTC); + let dussehra = datetime!(2023-10-24 12:00:00 UTC); + let diwali = datetime!(2024-10-31 12:00:00 UTC); + let gurunanak_jayanti = datetime!(2024-11-15 12:00:00 UTC); + let christmas = datetime!(2024-12-25 12:00:00 UTC); + + assert!(!calendar.is_business_day(republic_day)); + assert!(!calendar.is_business_day(mahashivratri)); + assert!(!calendar.is_business_day(holi)); + assert!(!calendar.is_business_day(good_friday)); + assert!(!calendar.is_business_day(eid_ul_fitar)); + assert!(!calendar.is_business_day(rama_navami)); + assert!(!calendar.is_business_day(mahavir_jayanti)); + assert!(!calendar.is_business_day(maharashtra_day)); + assert!(!calendar.is_business_day(bakri_id)); + assert!(!calendar.is_business_day(muharram)); + assert!(!calendar.is_business_day(independence_day)); + assert!(!calendar.is_business_day(gandhi_jayanti)); + assert!(!calendar.is_business_day(dussehra)); + assert!(!calendar.is_business_day(diwali)); + assert!(!calendar.is_business_day(gurunanak_jayanti)); + assert!(!calendar.is_business_day(christmas)); + } + + // Test to verify if the is_business_day() method properly accounts for regular business days. + #[test] + fn test_is_regular_business_day() { + let calendar = India; + let regular_day1 = datetime!(2024-03-22 12:00:00 UTC); + let regular_day2 = datetime!(2024-10-30 12:00:00 UTC); + let regular_day3 = datetime!(2024-12-09 12:00:00 UTC); + + assert!(calendar.is_business_day(regular_day1)); + assert!(calendar.is_business_day(regular_day2)); + assert!(calendar.is_business_day(regular_day3)); + } +} diff --git a/src/time/calendars/indonesia.rs b/src/time/calendars/indonesia.rs index a087594c..12b28075 100644 --- a/src/time/calendars/indonesia.rs +++ b/src/time/calendars/indonesia.rs @@ -8,21 +8,65 @@ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ use crate::time::Calendar; -use time::{Month, OffsetDateTime, Weekday}; +use time::{Month, OffsetDateTime}; -/// Czech Republic calendar. -pub struct CzechRepublic; +/// Indonesia calendar. +pub struct Indonesia; -impl Calendar for CzechRepublic { +impl Calendar for Indonesia { fn name(&self) -> &'static str { - "" + "Indonesia" + } + + fn country_code(&self) -> crate::iso::ISO_3166 { + crate::iso::INDONESIA + } + + fn market_identifier_code(&self) -> crate::iso::ISO_10383 { + crate::iso::XIDX } fn is_business_day(&self, date: OffsetDateTime) -> bool { - let (w, d, m, y, dd) = self.unpack_date(date); + let (_, d, m, y, dd) = self.unpack_date(date); let em = Self::easter_monday(y as usize, false); - if Self::is_weekend(date) { + if Self::is_weekend(date) + // New Year's Day + || (d == 1 && m == Month::January) + // Ascension of the Prophet Muhammad + || is_ascension_day_of_prophet_muhammad(y,d,m) + // Lunar New Year + || is_lunar_new_year(y,d,m) + // Hindu New year + || is_hindu_new_year(y,d,m) + // Good Friday + || (dd == em - 3) + // Eid-ul-Fitar + || is_eid_ul_fitar(y,d,m) + // Labor Day + || (d == 1 && m == Month::May) + // Ascension Day of Jesus Christ + || (dd == em + 38) + || (y == 2007 && m == Month::May && d==18) + || (y == 2008 && m == Month::May && d==2) + || (y == 2024 && m == Month::May && d==10) + // Vesak Day + || is_vesak_day(y,d,m) + // Pancasila Day + || (d == 1 && m == Month::June) + // Eid-ul-Adha + || is_eid_ul_adha(y,d,m) + // Muharram + || is_muharram(y,d,m) + // Independence Day + || (d==17 && m==Month::August) + // Birth of Prophet Muhammad + || is_birth_of_prophet_muhammad(y,d,m) + // Christmas + || (d == 25 && m==Month::December) + // Boxing Day + || (d == 26 && m == Month::December) + { return false; } @@ -30,9 +74,348 @@ impl Calendar for CzechRepublic { } } +#[allow(clippy::unnested_or_patterns)] +fn is_ascension_day_of_prophet_muhammad(year: i32, day: u8, month: Month) -> bool { + matches!( + (year, day, month), + (2000, 26, Month::October) + | (2001, 15, Month::October) + | (2002, 4, Month::October) + | (2003, 24, Month::September) + | (2004, 12, Month::September) + | (2005, 1, Month::September) + | (2006, 22, Month::August) + | (2007, 11, Month::August) + | (2008, 31, Month::July) + | (2009, 20, Month::July) + | (2010, 9, Month::July) + | (2011, 29, Month::June) + | (2012, 17, Month::June) + | (2013, 6, Month::June) + | (2014, 27, Month::May) + | (2015, 16, Month::May) + | (2016, 6, Month::May) + | (2017, 24, Month::April) + | (2018, 14, Month::April) + | (2019, 3, Month::April) + | (2020, 22, Month::March) + | (2021, 11, Month::March) + | (2022, 28, Month::February) + | (2023, 18, Month::February) + | (2024, 8, Month::February) + ) +} + +#[allow(clippy::unnested_or_patterns)] +fn is_lunar_new_year(year: i32, day: u8, month: Month) -> bool { + use Month::{February, January}; + matches!( + (year, day, month), + (2000, 5, February) + | (2001, 24, January) + | (2002, 12, February) + | (2003, 1, February) + | (2004, 22, January) + | (2005, 9, February) + | (2006, 30, January) + | (2007, 19, February) + | (2008, 7, February) + | (2009, 26, January) + | (2010, 15, February) + | (2011, 3, February) + | (2012, 23, January) + | (2013, 11, February) + | (2014, 31, January) + | (2015, 19, February) + | (2016, 8, February) + | (2017, 28, January) + | (2018, 16, February) + | (2019, 5, February) + | (2020, 25, January) + | (2021, 12, February) + | (2022, 1, February) + | (2023, 23, January) + | (2024, 9, February) + | (2025, 29, January) + ) +} + +#[allow(clippy::unnested_or_patterns)] +fn is_hindu_new_year(year: i32, day: u8, month: Month) -> bool { + use Month::March; + matches!( + (year, day, month), + (2006, 30, March) + | (2007, 19, March) + | (2008, 7, March) + | (2009, 26, March) + | (2010, 16, March) + | (2011, 5, March) + | (2012, 23, March) + | (2013, 12, March) + | (2014, 31, March) + | (2015, 21, March) + | (2016, 9, March) + | (2017, 28, March) + | (2018, 17, March) + | (2019, 7, March) + | (2020, 25, March) + | (2021, 14, March) + | (2022, 3, March) + | (2023, 22, March) + | (2023, 23, March) + | (2024, 11, March) + | (2024, 12, March) + ) +} + +#[allow(clippy::unnested_or_patterns)] +fn is_eid_ul_fitar(year: i32, day: u8, month: Month) -> bool { + matches!( + (year, day, month), + (2006, 23, Month::October) + | (2007, 12, Month::October) + | (2008, 29, Month::September) + | (2008, 30, Month::September) + | (2010, 9, Month::September) + | (2015, 16, Month::July) + | (2016, 4, Month::July) + | (2016, 5, Month::July) + | (2018, 11, Month::June) + | (2018, 12, Month::June) + | (2019, 3, Month::June) + | (2019, 4, Month::June) + | (2021, 12, Month::May) + | (2022, 29, Month::April) + | (2023, 19, Month::April) + | (2023, 20, Month::April) + | (2024, 8, Month::April) + | (2024, 9, Month::April) + | (2006, 26, Month::October) + | (2007, 15, Month::October) + | (2008, 3, Month::October) + | (2009, 23, Month::September) + | (2010, 13, Month::September) + | (2014, 30, Month::July) + | (2015, 20, Month::July) + | (2016, 8, Month::July) + | (2018, 18, Month::June) + | (2018, 13, Month::June) + | (2019, 7, Month::June) + | (2019, 6, Month::June) + | (2019, 5, Month::June) + | (2020, 25, Month::May) + | (2020, 24, Month::May) + | (2021, 14, Month::May) + | (2021, 17, Month::May) + | (2021, 13, Month::May) + | (2022, 2, Month::May) + | (2022, 3, Month::May) + | (2022, 4, Month::May) + | (2023, 21, Month::April) + | (2023, 24, Month::April) + | (2023, 22, Month::April) + | (2023, 23, Month::April) + | (2024, 12, Month::April) + | (2024, 15, Month::April) + | (2024, 11, Month::April) + | (2024, 10, Month::April) + | (2025, 1, Month::April) + | (2025, 2, Month::April) + ) +} + +#[allow(clippy::unnested_or_patterns)] +fn is_vesak_day(year: i32, day: u8, month: Month) -> bool { + use Month::{June, May}; + matches!( + (year, day, month), + (2007, 1, June) + | (2008, 19, May) + | (2008, 20, May) + | (2009, 9, May) + | (2010, 28, May) + | (2011, 17, May) + | (2012, 6, May) + | (2013, 25, May) + | (2014, 15, May) + | (2015, 2, June) + | (2016, 22, May) + | (2017, 11, May) + | (2018, 29, May) + | (2019, 19, May) + | (2020, 7, May) + | (2021, 26, May) + | (2022, 16, May) + | (2023, 4, June) + | (2023, 2, June) + | (2024, 23, May) + | (2024, 24, May) + | (2025, 13, May) + ) +} + +#[allow(clippy::unnested_or_patterns)] +fn is_eid_ul_adha(year: i32, day: u8, month: Month) -> bool { + use Month::{August, July, June}; + matches!( + (year, day, month), + (2019, 11, August) + | (2020, 31, July) + | (2021, 20, July) + | (2022, 10, July) + | (2023, 29, June) + | (2024, 17, June) + | (2024, 18, June) + | (2025, 7, June) + ) +} + +#[allow(clippy::unnested_or_patterns)] +fn is_muharram(year: i32, day: u8, month: Month) -> bool { + matches!( + (year, day, month), + (2000, 6, Month::April) + | (2001, 26, Month::March) + | (2002, 15, Month::March) + | (2003, 5, Month::March) + | (2004, 22, Month::February) + | (2005, 10, Month::February) + | (2006, 31, Month::January) + | (2007, 20, Month::January) + | (2008, 10, Month::January) + | (2008, 29, Month::December) + | (2009, 18, Month::December) + | (2010, 7, Month::December) + | (2011, 27, Month::November) + | (2012, 15, Month::November) + | (2013, 5, Month::November) + | (2014, 25, Month::October) + | (2015, 14, Month::October) + | (2016, 2, Month::October) + | (2017, 21, Month::September) + | (2018, 11, Month::September) + | (2019, 1, Month::September) + | (2020, 20, Month::August) + | (2021, 10, Month::August) + | (2021, 11, Month::August) + | (2022, 30, Month::July) + | (2023, 19, Month::July) + | (2024, 7, Month::July) + | (2025, 27, Month::June) + ) +} + +#[allow(clippy::unnested_or_patterns)] +fn is_birth_of_prophet_muhammad(year: i32, day: u8, month: Month) -> bool { + matches!( + (year, day, month), + (2006, 10, Month::April) + | (2007, 31, Month::March) + | (2008, 20, Month::March) + | (2009, 9, Month::March) + | (2010, 26, Month::February) + | (2011, 15, Month::February) + | (2012, 5, Month::February) + | (2013, 24, Month::January) + | (2014, 14, Month::January) + | (2015, 3, Month::January) + | (2015, 24, Month::December) + | (2016, 12, Month::December) + | (2017, 1, Month::December) + | (2018, 20, Month::November) + | (2019, 9, Month::November) + | (2020, 29, Month::October) + | (2021, 19, Month::October) + | (2021, 20, Month::October) + | (2022, 8, Month::October) + | (2023, 28, Month::September) + | (2024, 15, Month::September) + | (2025, 5, Month::September) + ) +} + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // UNIT TESTS // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #[cfg(test)] -mod tests {} +mod test_indonesia { + use super::*; + use time::macros::datetime; + + // Test to verify the name() method. + #[test] + fn test_name() { + let calendar = Indonesia; + assert_eq!(calendar.name(), "Indonesia"); + } + + // Test to verify if weekends are not considered business days. + #[test] + fn test_is_weekend() { + let calendar = Indonesia; + let sat = datetime!(2024-04-27 12:00:00 UTC); + let sun = datetime!(2024-04-28 12:00:00 UTC); + assert!(!calendar.is_business_day(sat)); + assert!(!calendar.is_business_day(sun)); + } + + // Test to verify if the is_business_day() method properly accounts for public holidays. + #[test] + fn test_is_public_holiday() { + let calendar = Indonesia; + let new_years_day = datetime!(2024-01-01 12:00:00 UTC); + let ascension_of_the_prophet_muhammad = datetime!(2024-02-08 12:00:00 UTC); + let lunar_new_year = datetime!(2024-02-09 12:00:00 UTC); + let hindu_new_year = datetime!(2024-03-11 12:00:00 UTC); + let hindu_new_year_2 = datetime!(2024-03-12 12:00:00 UTC); + let eid_ul_fitar = datetime!(2024-04-08 12:00:00 UTC); + let eid_ul_fitar_2 = datetime!(2024-04-15 12:00:00 UTC); + let labor_day = datetime!(2024-05-01 12:00:00 UTC); + let ascension_of_jesus_christ = datetime!(2024-05-09 12:00:00 UTC); + let ascension_of_jesus_christ_2 = datetime!(2024-05-10 12:00:00 UTC); + let vesak_day = datetime!(2024-05-24 12:00:00 UTC); + let pancasila_day = datetime!(2024-06-01 12:00:00 UTC); + let eid_ul_adha = datetime!(2024-06-17 12:00:00 UTC); + let eid_ul_adha_2 = datetime!(2024-06-18 12:00:00 UTC); + let muharram = datetime!(2024-07-07 12:00:00 UTC); + let independence_day = datetime!(2024-08-17 12:00:00 UTC); + let birth_of_prophet_muhammad = datetime!(2024-09-15 12:00:00 UTC); + let christmas = datetime!(2024-12-25 12:00:00 UTC); + let boxing_day = datetime!(2024-12-26 12:00:00 UTC); + + assert!(!calendar.is_business_day(new_years_day)); + assert!(!calendar.is_business_day(ascension_of_the_prophet_muhammad)); + assert!(!calendar.is_business_day(lunar_new_year)); + assert!(!calendar.is_business_day(hindu_new_year)); + assert!(!calendar.is_business_day(hindu_new_year_2)); + assert!(!calendar.is_business_day(eid_ul_fitar)); + assert!(!calendar.is_business_day(eid_ul_fitar_2)); + assert!(!calendar.is_business_day(labor_day)); + assert!(!calendar.is_business_day(ascension_of_jesus_christ)); + assert!(!calendar.is_business_day(ascension_of_jesus_christ_2)); + assert!(!calendar.is_business_day(vesak_day)); + assert!(!calendar.is_business_day(pancasila_day)); + assert!(!calendar.is_business_day(eid_ul_adha)); + assert!(!calendar.is_business_day(eid_ul_adha_2)); + assert!(!calendar.is_business_day(muharram)); + assert!(!calendar.is_business_day(independence_day)); + assert!(!calendar.is_business_day(birth_of_prophet_muhammad)); + assert!(!calendar.is_business_day(christmas)); + assert!(!calendar.is_business_day(boxing_day)); + } + + // Test to verify if the is_business_day() method properly accounts for regular business days. + #[test] + fn test_is_regular_business_day() { + let calendar = Indonesia; + let regular_day1 = datetime!(2024-06-19 12:00:00 UTC); + let regular_day2 = datetime!(2024-07-03 12:00:00 UTC); + let regular_day3 = datetime!(2024-11-07 12:00:00 UTC); + + assert!(calendar.is_business_day(regular_day1)); + assert!(calendar.is_business_day(regular_day2)); + assert!(calendar.is_business_day(regular_day3)); + } +} diff --git a/src/time/mod.rs b/src/time/mod.rs index 08adaf2d..9d19587a 100644 --- a/src/time/mod.rs +++ b/src/time/mod.rs @@ -14,7 +14,7 @@ pub use crate::time::{ calendars::{ argentina::*, australia::*, austria::*, botswana::*, brazil::*, canada::*, chile::*, china::*, czech_republic::*, denmark::*, finland::*, france::*, germany::*, hong_kong::*, - hungary::*, united_kingdom::*, united_states::*, + hungary::*, iceland::*, india::*, indonesia::*, united_kingdom::*, united_states::*, }, constants::*, conventions::*, @@ -65,6 +65,12 @@ pub mod calendars { pub mod hong_kong; /// Hungary settlement calendar. pub mod hungary; + /// Iceland settlement calendar. + pub mod iceland; + /// India settlement calendar. + pub mod india; + /// Indonesia settlement calendar. + pub mod indonesia; /// Calendar test module. mod tests; /// UK settlement calendar.