1use chrono::{Datelike, Local};
6use std::convert::TryInto;
7
8use crate::{
9 BengaliDate, BengaliMonths, BengaliWeekDays, Date, DateError, EnglishDate, EnglishMonths,
10};
11
12fn is_leap_year(year: u16) -> bool {
13 year % 4 == 0
14}
15
16fn gregorian_to_bengali_date(english_date: EnglishDate) -> Result<Date, DateError> {
24 let (english_day, english_month, english_year) = english_date.get_date();
25
26 let bengali_year: u16 = if english_month < 4 || (english_month == 4 && english_day < 14) {
30 match english_year.checked_sub(594) {
31 Some(year) => year,
32 None => {
33 return Err(DateError::ArithmeticError);
34 }
35 }
36 } else {
37 match english_year.checked_sub(593) {
38 Some(year) => year,
39 None => {
40 return Err(DateError::ArithmeticError);
41 }
42 }
43 };
44
45 let (bengali_day, bengali_month) = if english_month == 1 {
47 if english_day <= 14 {
48 (english_day + 16, 9)
49 } else {
50 (english_day - 14, 10)
51 }
52 } else if english_month == 2 {
53 if english_day <= 13 {
54 (english_day + 17, 10)
55 } else {
56 (english_day - 13, 11)
57 }
58 } else if english_month == 3 {
59 if english_day <= 14 {
60 if is_leap_year(english_year) {
61 (english_day + 16, 11)
62 } else {
63 (english_day + 15, 11)
64 }
65 } else {
66 (english_day - 14, 12)
67 }
68 } else if english_month == 4 {
69 if english_day <= 13 {
70 (english_day + 17, 12)
71 } else {
72 (english_day - 13, 1)
73 }
74 } else if english_month == 5 {
75 if english_day <= 14 {
76 (english_day + 17, 1)
77 } else {
78 (english_day - 14, 2)
79 }
80 } else if english_month == 6 {
81 if english_day <= 14 {
82 (english_day + 17, 2)
83 } else {
84 (english_day - 14, 3)
85 }
86 } else if english_month == 7 {
87 if english_day <= 15 {
88 (english_day + 16, 3)
89 } else {
90 (english_day - 15, 4)
91 }
92 } else if english_month == 8 {
93 if english_day <= 15 {
94 (english_day + 16, 4)
95 } else {
96 (english_day - 15, 5)
97 }
98 } else if english_month == 9 {
99 if english_day <= 15 {
100 (english_day + 16, 5)
101 } else {
102 (english_day - 15, 6)
103 }
104 } else if english_month == 10 {
105 if english_day <= 16 {
106 (english_day + 15, 6)
107 } else {
108 (english_day - 16, 7)
109 }
110 } else if english_month == 11 {
111 if english_day <= 15 {
112 (english_day + 15, 7)
113 } else {
114 (english_day - 15, 8)
115 }
116 } else if english_month == 12 {
117 if english_day <= 15 {
118 (english_day + 15, 8)
119 } else {
120 (english_day - 15, 9)
121 }
122 } else {
123 return Err(DateError::WrongDay);
124 };
125
126 let bengali_weekday =
127 BengaliWeekDays::get_english_weekday(english_date.get_week_day().unwrap().as_str());
128
129 match BengaliDate::create_date_with_weekday(
130 bengali_day,
131 bengali_weekday.unwrap(),
132 BengaliMonths::get_month(bengali_month).unwrap(),
133 bengali_year,
134 ) {
135 Ok(bengali_date) => Ok(Date::Bengali(bengali_date)),
136 Err(err) => Err(err),
137 }
138}
139
140fn bengali_to_gregorian_date(bengali_date: BengaliDate) -> Result<Date, DateError> {
148 let (bengali_day, bengali_month, bengali_year) = bengali_date.get_date();
149
150 let english_year: u16 = if (bengali_month == 9 && bengali_day >= 17)
151 || (bengali_month == 12 && bengali_day <= 30)
152 || bengali_month == 10
153 || bengali_month == 11
154 {
155 match bengali_year.checked_add(594) {
156 Some(year) => year,
157 None => return Err(DateError::ArithmeticError),
158 }
159 } else {
160 match bengali_year.checked_add(593) {
161 Some(year) => year,
162 None => return Err(DateError::ArithmeticError),
163 }
164 };
165
166 let (english_date, english_month) = if bengali_month == 9 {
167 if bengali_day >= 17 {
168 (bengali_day - 16, 1)
169 } else {
170 (bengali_day + 15, 12)
171 }
172 } else if bengali_month == 10 {
173 if bengali_day >= 18 {
174 (bengali_day - 17, 2)
175 } else {
176 (bengali_day + 14, 1)
177 }
178 } else if bengali_month == 11 {
179 if is_leap_year(english_year) {
180 if bengali_day >= 17 {
181 (bengali_day - 16, 3)
182 } else {
183 (bengali_day + 13, 2)
184 }
185 } else {
186 if bengali_day >= 16 {
187 (bengali_day - 15, 3)
188 } else {
189 (bengali_day + 13, 2)
190 }
191 }
192 } else if bengali_month == 12 {
193 if bengali_day >= 18 {
194 (bengali_day - 17, 4)
195 } else {
196 (bengali_day + 14, 3)
197 }
198 } else if bengali_month == 1 {
199 if bengali_day >= 18 {
200 (bengali_day - 17, 5)
201 } else {
202 (bengali_day + 13, 4)
203 }
204 } else if bengali_month == 2 {
205 if bengali_day >= 18 {
206 (bengali_day - 17, 6)
207 } else {
208 (bengali_day + 14, 5)
209 }
210 } else if bengali_month == 3 {
211 if bengali_day >= 17 {
212 (bengali_day - 16, 7)
213 } else {
214 (bengali_day + 14, 6)
215 }
216 } else if bengali_month == 4 {
217 if bengali_day >= 17 {
218 (bengali_day - 16, 8)
219 } else {
220 (bengali_day + 15, 7)
221 }
222 } else if bengali_month == 5 {
223 if bengali_day >= 17 {
224 (bengali_day - 16, 9)
225 } else {
226 (bengali_day + 15, 8)
227 }
228 } else if bengali_month == 6 {
229 if bengali_day >= 16 {
230 (bengali_day - 15, 10)
231 } else {
232 (bengali_day + 15, 9)
233 }
234 } else if bengali_month == 7 {
235 if bengali_day >= 16 {
236 (bengali_day - 15, 11)
237 } else {
238 (bengali_day + 16, 10)
239 }
240 } else if bengali_month == 8 {
241 if bengali_day >= 16 {
242 (bengali_day - 15, 12)
243 } else {
244 (bengali_day + 15, 11)
245 }
246 } else {
247 return Err(DateError::WrongDay);
248 };
249
250 match EnglishDate::create_date(
251 english_date,
252 EnglishMonths::get_month(english_month).unwrap(),
253 english_year,
254 ) {
255 Ok(english_date) => Ok(Date::English(english_date)),
256 Err(err) => Err(err),
257 }
258}
259
260pub fn get_today_bengali_date() -> Result<Date, DateError> {
279 let today = Local::now();
280
281 let today_day: u8 = match today.day().try_into() {
282 Ok(day) => day,
283 Err(err) => {
284 return Err(DateError::CastingError(err)); }
286 };
287
288 let today_month: u8 = match today.month().try_into() {
289 Ok(month) => month,
290 Err(err) => {
291 return Err(DateError::CastingError(err)); }
293 };
294
295 let today_year: u16 = match today.year().try_into() {
296 Ok(year) => year,
297 Err(err) => {
298 return Err(DateError::CastingError(err)); }
300 };
301
302 match EnglishMonths::get_month(today_month) {
303 Ok(month) => {
304 let english_date = EnglishDate::create_date(today_day, month, today_year);
305
306 match english_date {
307 Ok(date) => match gregorian_to_bengali_date(date) {
308 Ok(bengali_date) => Ok(bengali_date),
309 Err(err) => Err(err),
310 },
311 Err(err) => return Err(err),
312 }
313 }
314 Err(err) => match err {
315 _ => return Err(DateError::WrongMonth(err)),
316 },
317 }
318}
319
320pub fn get_bengali_date_from_gregorian(english_date: EnglishDate) -> Result<Date, DateError> {
349 match gregorian_to_bengali_date(english_date) {
350 Ok(date) => Ok(date),
351 Err(err) => Err(err),
352 }
353}
354
355pub fn get_gregorian_date_from_bengali(bengali_date: BengaliDate) -> Result<Date, DateError> {
384 match bengali_to_gregorian_date(bengali_date) {
385 Ok(date) => Ok(date),
386 Err(err) => Err(err),
387 }
388}