1pub mod canchi;
11pub mod gio_hoang_dao;
12pub mod holiday_data;
13pub mod holidays;
14pub mod insight_data;
15pub mod julian;
16pub mod lunar;
17pub mod sun;
18pub mod tietkhi;
19pub mod types;
20
21pub use types::*;
23
24use canchi::{get_day_canchi, get_month_canchi, get_year_canchi};
25use gio_hoang_dao::{get_gio_hoang_dao, GioHoangDao};
26use julian::jd_from_date;
27use lunar::convert_solar_to_lunar;
28use tietkhi::{get_tiet_khi, SolarTerm};
29
30#[derive(Debug, Clone)]
32pub struct SolarInfo {
33 pub day: i32,
34 pub month: i32,
35 pub year: i32,
36 pub day_of_week: usize,
37 pub day_of_week_name: String,
38 pub date_string: String,
39}
40
41#[derive(Debug, Clone)]
43pub struct LunarInfo {
44 pub day: i32,
45 pub month: i32,
46 pub year: i32,
47 pub is_leap_month: bool,
48 pub date_string: String,
49}
50
51#[derive(Debug, Clone)]
53pub struct CanChiInfo {
54 pub day: CanChi,
55 pub month: CanChi,
56 pub year: CanChi,
57 pub full: String,
58}
59
60#[derive(Debug, Clone)]
62pub struct DayInfo {
63 pub solar: SolarInfo,
64 pub lunar: LunarInfo,
65 pub jd: i32,
66 pub canchi: CanChiInfo,
67 pub tiet_khi: SolarTerm,
68 pub gio_hoang_dao: GioHoangDao,
69}
70
71pub fn get_day_info(day: i32, month: i32, year: i32) -> DayInfo {
91 get_day_info_with_timezone(day, month, year, VIETNAM_TIMEZONE)
92}
93
94pub fn get_day_info_with_timezone(day: i32, month: i32, year: i32, time_zone: f64) -> DayInfo {
105 let jd = jd_from_date(day, month, year);
107
108 let lunar_date = convert_solar_to_lunar(day, month, year, time_zone);
110
111 let day_of_week = ((jd + 1) % 7) as usize;
113
114 let day_canchi = get_day_canchi(jd);
116 let month_canchi = get_month_canchi(lunar_date.month, lunar_date.year, lunar_date.is_leap);
117 let year_canchi = get_year_canchi(lunar_date.year);
118
119 let tiet_khi = get_tiet_khi(jd, time_zone);
121
122 let gio_hoang_dao = get_gio_hoang_dao(day_canchi.chi_index);
124
125 let solar = SolarInfo {
127 day,
128 month,
129 year,
130 day_of_week,
131 day_of_week_name: THU[day_of_week].to_string(),
132 date_string: format!("{}-{:02}-{:02}", year, month, day),
133 };
134
135 let lunar = LunarInfo {
137 day: lunar_date.day,
138 month: lunar_date.month,
139 year: lunar_date.year,
140 is_leap_month: lunar_date.is_leap,
141 date_string: format!(
142 "{}/{}/{}{}",
143 lunar_date.day,
144 lunar_date.month,
145 lunar_date.year,
146 if lunar_date.is_leap { " (nhuận)" } else { "" }
147 ),
148 };
149
150 let canchi = CanChiInfo {
152 day: day_canchi.clone(),
153 month: month_canchi.clone(),
154 year: year_canchi.clone(),
155 full: format!(
156 "{}, tháng {}, năm {}",
157 day_canchi.full, month_canchi.full, year_canchi.full
158 ),
159 };
160
161 DayInfo {
162 solar,
163 lunar,
164 jd,
165 canchi,
166 tiet_khi,
167 gio_hoang_dao,
168 }
169}
170
171#[cfg(test)]
172mod tests {
173 use super::*;
174
175 #[test]
176 fn test_get_day_info_tet_2024() {
177 let info = get_day_info(10, 2, 2024);
179
180 assert_eq!(info.solar.day, 10);
182 assert_eq!(info.solar.month, 2);
183 assert_eq!(info.solar.year, 2024);
184
185 assert_eq!(info.lunar.day, 1);
187 assert_eq!(info.lunar.month, 1);
188 assert_eq!(info.lunar.year, 2024);
189 assert!(!info.lunar.is_leap_month);
190
191 assert_eq!(info.canchi.day.full, "Giáp Thìn");
193 assert_eq!(info.canchi.year.full, "Giáp Thìn");
194 }
195
196 #[test]
197 fn test_get_day_info_tet_2025() {
198 let info = get_day_info(29, 1, 2025);
200
201 assert_eq!(info.lunar.day, 1);
203 assert_eq!(info.lunar.month, 1);
204 assert_eq!(info.lunar.year, 2025);
205
206 assert_eq!(info.canchi.day.full, "Mậu Tuất");
208 assert_eq!(info.canchi.year.full, "Ất Tỵ");
209 }
210
211 #[test]
212 fn test_day_of_week() {
213 let info = get_day_info(1, 1, 2000);
215 assert_eq!(info.solar.day_of_week, 6);
216 assert_eq!(info.solar.day_of_week_name, "Thứ Bảy");
217 }
218
219 #[test]
220 fn test_gio_hoang_dao_present() {
221 let info = get_day_info(10, 2, 2024);
222
223 assert_eq!(info.gio_hoang_dao.good_hour_count, 6);
225 assert_eq!(info.gio_hoang_dao.good_hours.len(), 6);
226 }
227
228 #[test]
229 fn test_custom_timezone() {
230 let info = get_day_info_with_timezone(10, 2, 2024, 8.0);
232
233 assert_eq!(info.solar.day, 10);
235 assert_eq!(info.solar.month, 2);
236 assert_eq!(info.solar.year, 2024);
237 }
238}