finquant/time/calendars/
indonesia.rs

1// Holidays in Indonesia.
2
3use crate::time::calendars::Calendar;
4
5use chrono::NaiveDate;
6use serde::{Deserialize, Serialize};
7
8#[derive(Deserialize, Serialize, Default, Debug)]
9pub struct Indonesia;
10
11#[typetag::serde]
12impl Calendar for Indonesia {
13    fn is_business_day(&self, date: NaiveDate) -> bool {
14        let (d, _, m, y, dd) = self.naive_date_to_dkmy(date);
15        let em = self.easter_monday(y);
16
17        if self.is_weekend(date)
18            // New Year's Day
19            || (d == 1 && m == 1)
20            // Good Friday
21            || (dd == em-3)
22            // Ascension Thursday
23            || (dd == em+38)
24            // Independence Day
25            || (d == 17 && m == 8)
26            // Christmas
27            || (d == 25 && m == 12)
28        {
29            return false;
30        }
31
32        if (y == 2005) & // Idul Adha
33            ((d == 21 && m == 1)
34                    // Imlek
35                    || (d == 9 && m == 2)
36                    // Moslem's New Year Day
37                    || (d == 10 && m == 2)
38                    // Nyepi
39                    || (d == 11 && m == 3)
40                    // Birthday of Prophet Muhammad SAW
41                    || (d == 22 && m == 4)
42                    // Waisak
43                    || (d == 24 && m == 5)
44                    // Ascension of Prophet Muhammad SAW
45                    || (d == 2 && m == 9)
46                    // Idul Fitri
47                    || ((d == 3 || d == 4) && m == 11)
48                    // National leaves
49                    || ((d == 2 || d == 7 || d == 8) && m == 11)
50                    || (d == 26 && m == 12))
51        {
52            return false;
53        }
54
55        if (y == 2006) & // Idul Adha
56            (!(m != 1 || d != 10 && d != 31)
57                    // Nyepi
58                    || (d == 30 && m == 3)
59                    // Birthday of Prophet Muhammad SAW
60                    || (d == 10 && m == 4)
61                    // Ascension of Prophet Muhammad SAW
62                    || (d == 21 && m == 8)
63                    // Idul Fitri
64                    || ((d == 24 || d == 25) && m == 10)
65                    // National leaves
66                    || ((d == 23 || d == 26 || d == 27) && m == 10))
67        {
68            return false;
69        }
70
71        if (y == 2007) & // Nyepi
72            ((d == 19 && m == 3)
73                    // Waisak
74                    || (d == 1 && m == 6)
75                    // Ied Adha
76                    || (d == 20 && m == 12)
77                    // National leaves
78                    || (d == 18 && m == 5)
79                    || ((d == 12 || d == 15 || d == 16) && m == 10)
80                    || ((d == 21 || d == 24) && m == 10))
81        {
82            return false;
83        }
84
85        if (y == 2008) & // Islamic New Year
86            (((d == 10 || d == 11) && m == 1)
87                    // Chinese New Year
88                    || ((d == 7 || d == 8) && m == 2)
89                    // Saka's New Year
90                    || (d == 7 && m == 3)
91                    // Birthday of the prophet Muhammad SAW
92                    || (d == 20 && m == 3)
93                    // Vesak Day
94                    || (d == 20 && m == 5)
95                    // Isra' Mi'raj of the prophet Muhammad SAW
96                    || (d == 30 && m == 7)
97                    // National leave
98                    || (d == 18 && m == 8)
99                    // Ied Fitr
100                    || (d == 30 && m == 9)
101                    || ((d == 1 || d == 2 || d == 3) && m == 10)
102                    // Ied Adha
103                    || (d == 8 && m == 12)
104                    // Islamic New Year
105                    || (d == 29 && m == 12)
106                    // New Year's Eve
107                    || (d == 31 && m == 12))
108        {
109            return false;
110        }
111
112        if (y == 2009) & // Public holiday
113            (!(m != 1 || d != 2 && d != 26)
114                    // Birthday of the prophet Muhammad SAW
115                    || (d == 9 && m == 3)
116                    // Saka's New Year
117                    || (d == 26 && m == 3)
118                    // National leave
119                    || (d == 9 && m == 4)
120                    // Isra' Mi'raj of the prophet Muhammad SAW
121                    || (d == 20 && m == 7)
122                    // Ied Fitr
123                    || ((18..=23).contains(&d) && m == 9)
124                    // Ied Adha
125                    || (d == 27 && m == 11)
126                    // Islamic New Year
127                    || (d == 18 && m == 12)
128                    // Public Holiday
129                    || (d == 24 && m == 12)
130                    // Trading holiday
131                    || (d == 31 && m == 12))
132        {
133            return false;
134        }
135
136        if (y == 2010) & // Birthday of the prophet Muhammad SAW
137            ((d == 26 && m == 2)
138                    // Saka's New Year
139                    || (d == 16 && m == 3)
140                    // Birth of Buddha
141                    || (d == 28 && m == 5)
142                    // Ied Fitr
143                    || ((8..=14).contains(&d) && m == 9)
144                    // Ied Adha
145                    || (d == 17 && m == 11)
146                    // Islamic New Year
147                    || (d == 7 && m == 12)
148                    // Public Holiday
149                    || (d == 24 && m == 12)
150                    // Trading holiday
151                    || (d == 31 && m == 12))
152        {
153            return false;
154        }
155
156        if (y == 2011) & // Chinese New Year
157            (!(m != 2 || d != 3 && d != 15)
158                // Birth of Buddha
159                    || (d == 17 && m == 5)
160                    // Isra' Mi'raj of the prophet Muhammad SAW
161                    || (d == 29 && m == 6)
162                    // Ied Fitr
163                    || (d >= 29 && m == 8)
164                    || (d <= 2 && m == 9)
165                    // Public Holiday
166                    || (d == 26 && m == 12))
167        {
168            return false;
169        }
170
171        if (y == 2012) & // Chinese New Year
172            (!(d != 23 || m != 1 && m != 3)
173                    // Ied ul-Fitr
174                    || ((20..=22).contains(&d) && m == 8)
175                    // Eid ul-Adha
176                    || (d == 26 && m == 10)
177                    // Islamic New Year
178                    || ((15..=16).contains(&d) && m == 11)
179                    // Public Holiday
180                    || (d == 24 && m == 12)
181                    // Trading Holiday
182                    || (d == 31 && m == 12))
183        {
184            return false;
185        }
186
187        if (y == 2013) & // Birthday of the prophet Muhammad SAW
188            ((d == 24 && m == 1)
189                    // Saka New Year
190                    || (d == 12 && m == 3)
191                    // Isra' Mi'raj of the prophet Muhammad SAW
192                    || (d == 6 && m == 6)
193                    // Ied ul-Fitr
194                    || ((5..=9).contains(&d) && m == 8)
195                    // Eid ul-Adha
196                    || ((14..=15).contains(&d) && m == 10)
197                    // Islamic New Year
198                    || (d == 5 && m == 11)
199                    // Public Holiday
200                    || (d == 26 && m == 12)
201                    // Trading Holiday
202                    || (d == 31 && m == 12))
203        {
204            return false;
205        }
206
207        if (y == 2014) & // Birthday of the prophet Muhammad SAW
208            (!(m != 1 || d != 14 && d != 31)
209                    // Saka New Year
210                    || (d == 31 && m == 3)
211                    // Labour Day
212                    || (d == 1 && m == 5)
213                    // Birth of Buddha
214                    || (d == 15 && m == 5)
215                    // Isra' Mi'raj of the prophet Muhammad SAW
216                    || (d == 27 && m == 5)
217                    // Ascension Day of Jesus Christ
218                    || (d == 29 && m == 5)
219                    // Ied ul-Fitr
220                    || ((d >= 28 && m == 7) || (d == 1 && m == 8))
221                    // Public Holiday
222                    || (d == 26 && m == 12)
223                    // Trading Holiday
224                    || (d == 31 && m == 12))
225        {
226            return false;
227        }
228
229        true
230    }
231}
232
233#[cfg(test)]
234mod tests {
235    use super::Indonesia;
236    use crate::time::calendars::Calendar;
237    use chrono::{Duration, NaiveDate};
238
239    #[test]
240    fn test_indonesia_holiday() {
241        // Test all results from 2023-01-01 to 2023-12-31
242        let expected_results_for_2023 = vec![
243            false, true, true, true, true, true, false, false, true, true, true, true, true, false,
244            false, true, true, true, true, true, false, false, true, true, true, true, true, false,
245            false, true, true, true, true, true, false, false, true, true, true, true, true, false,
246            false, true, true, true, true, true, false, false, true, true, true, true, true, false,
247            false, true, true, true, true, true, false, false, true, true, true, true, true, false,
248            false, true, true, true, true, true, false, false, true, true, true, true, true, false,
249            false, true, true, true, true, true, false, false, true, true, true, true, false,
250            false, false, true, true, true, true, true, false, false, true, true, true, true, true,
251            false, false, true, true, true, true, true, false, false, true, true, true, true, true,
252            false, false, true, true, true, true, true, false, false, true, true, true, false,
253            true, false, false, true, true, true, true, true, false, false, true, true, true, true,
254            true, false, false, true, true, true, true, true, false, false, true, true, true, true,
255            true, false, false, true, true, true, true, true, false, false, true, true, true, true,
256            true, false, false, true, true, true, true, true, false, false, true, true, true, true,
257            true, false, false, true, true, true, true, true, false, false, true, true, true, true,
258            true, false, false, true, true, true, true, true, false, false, true, true, true, true,
259            true, false, false, true, true, true, false, true, false, false, true, true, true,
260            true, true, false, false, true, true, true, true, true, false, false, true, true, true,
261            true, true, false, false, true, true, true, true, true, false, false, true, true, true,
262            true, true, false, false, true, true, true, true, true, false, false, true, true, true,
263            true, true, false, false, true, true, true, true, true, false, false, true, true, true,
264            true, true, false, false, true, true, true, true, true, false, false, true, true, true,
265            true, true, false, false, true, true, true, true, true, false, false, true, true, true,
266            true, true, false, false, true, true, true, true, true, false, false, true, true, true,
267            true, true, false, false, true, true, true, true, true, false, false, true, true, true,
268            true, true, false, false, true, true, true, true, true, false, false, false, true,
269            true, true, true, false, false,
270        ];
271        let first_date = NaiveDate::from_ymd_opt(2023, 1, 1).unwrap();
272        for n in 0i32..365 {
273            let target_date = first_date + Duration::try_days(n as i64).unwrap();
274            let expected = expected_results_for_2023[n as usize];
275            assert_eq!(Indonesia.is_business_day(target_date), expected);
276        }
277    }
278}