practical_astronomy_rust/
datetime.rs1use crate::macros as pa_m;
2use crate::util as pa_u;
3
4pub fn get_date_of_easter(input_year: u32) -> (u32, u32, u32) {
14 let year = input_year as f64;
15
16 let a = year % 19.0;
17 let b = (year / 100.0).floor();
18 let c = year % 100.0;
19 let d = (b / 4.0).floor();
20 let e = b % 4.0;
21 let f = ((b + 8.0) / 25.0).floor();
22 let g = ((b - f + 1.0) / 3.0).floor();
23 let h = ((19.0 * a) + b - d - g + 15.0) % 30.0;
24 let i = (c / 4.0).floor();
25 let k = c % 4.0;
26 let l = (32.0 + 2.0 * (e + i) - h - k) % 7.0;
27 let m = ((a + (11.0 * h) + (22.0 * l)) / 451.0).floor();
28 let n = ((h + l - (7.0 * m) + 114.0) / 31.0).floor();
29 let p = (h + l - (7.0 * m) + 114.0) % 31.0;
30
31 let day = p + 1.0;
32 let month = n;
33
34 return (month as u32, day as u32, year as u32);
35}
36
37pub fn civil_date_to_day_number(mut month: u32, day: u32, year: u32) -> u32 {
47 if month <= 2 {
48 month = month - 1;
49 month = if pa_u::is_leap_year(year) {
50 month * 62
51 } else {
52 month * 63
53 };
54 month = (month as f64 / 2.0).floor() as u32;
55 } else {
56 month = ((month as f64 + 1.0) * 30.6).floor() as u32;
57 month = if pa_u::is_leap_year(year) {
58 month - 62
59 } else {
60 month - 63
61 };
62 }
63
64 return month + day;
65}
66
67pub fn civil_time_to_decimal_hours(hours: f64, minutes: f64, seconds: f64) -> f64 {
69 return pa_m::hms_dh(hours, minutes, seconds as f64);
70}
71
72pub fn decimal_hours_to_civil_time(decimal_hours: f64) -> (f64, f64, f64) {
78 let hours = pa_m::dh_hour(decimal_hours);
79 let minutes = pa_m::dh_min(decimal_hours);
80 let seconds = pa_m::dh_sec(decimal_hours);
81
82 return (hours as f64, minutes as f64, seconds as f64);
83}
84
85pub fn local_civil_time_to_universal_time(
91 lct_hours: f64,
92 lct_minutes: f64,
93 lct_seconds: f64,
94 is_daylight_savings: bool,
95 zone_correction: i32,
96 local_day: f64,
97 local_month: u32,
98 local_year: u32,
99) -> (u32, u32, u32, u32, u32, u32) {
100 let lct = civil_time_to_decimal_hours(lct_hours, lct_minutes, lct_seconds);
101
102 let daylight_savings_offset = if is_daylight_savings == true { 1 } else { 0 };
103
104 let ut_interim = lct - daylight_savings_offset as f64 - zone_correction as f64;
105 let gday_interim = local_day as f64 + (ut_interim / 24.0);
106
107 let jd = pa_m::cd_jd(gday_interim, local_month, local_year);
108
109 let g_day = pa_m::jdc_day(jd) as f64;
110 let g_month = pa_m::jdc_month(jd);
111 let g_year = pa_m::jdc_year(jd);
112
113 let ut = 24.0 * (g_day - g_day.floor());
114
115 return (
116 pa_m::dh_hour(ut),
117 pa_m::dh_min(ut),
118 pa_m::dh_sec(ut) as u32,
119 g_day.floor() as u32,
120 g_month,
121 g_year,
122 );
123}
124
125pub fn universal_time_to_local_civil_time(
131 ut_hours: f64,
132 ut_minutes: f64,
133 ut_seconds: f64,
134 is_daylight_savings: bool,
135 zone_correction: i32,
136 gw_day: u32,
137 gw_month: u32,
138 gw_year: u32,
139) -> (u32, u32, u32, u32, u32, u32) {
140 let dst_value = if is_daylight_savings == true { 1 } else { 0 };
141 let ut = pa_m::hms_dh(ut_hours, ut_minutes, ut_seconds);
142 let zone_time = ut + zone_correction as f64;
143 let local_time = zone_time + dst_value as f64;
144 let local_jd_plus_local_time =
145 pa_m::cd_jd(gw_day as f64, gw_month, gw_year) + (local_time / 24.0);
146 let local_day = pa_m::jdc_day(local_jd_plus_local_time) as f64;
147 let integer_day = local_day.floor();
148 let local_month = pa_m::jdc_month(local_jd_plus_local_time);
149 let local_year = pa_m::jdc_year(local_jd_plus_local_time);
150
151 let lct = 24.0 * (local_day - integer_day as f64);
152
153 return (
154 pa_m::dh_hour(lct),
155 pa_m::dh_min(lct),
156 pa_m::dh_sec(lct) as u32,
157 integer_day as u32,
158 local_month,
159 local_year,
160 );
161}
162
163pub fn universal_time_to_greenwich_sidereal_time(
168 ut_hours: f64,
169 ut_minutes: f64,
170 ut_seconds: f64,
171 gw_day: f64,
172 gw_month: u32,
173 gw_year: u32,
174) -> (u32, u32, f64) {
175 let jd = pa_m::cd_jd(gw_day as f64, gw_month, gw_year);
176 let s = jd - 2451545.0;
177 let t = s / 36525.0;
178 let t01 = 6.697374558 + (2400.051336 * t) + (0.000025862 * t * t);
179 let t02 = t01 - (24.0 * (t01 / 24.0).floor());
180 let ut = pa_m::hms_dh(ut_hours, ut_minutes, ut_seconds);
181 let a = ut * 1.002737909;
182 let gst1 = t02 + a;
183 let gst2 = gst1 - (24.0 * (gst1 / 24.0).floor());
184
185 let gst_hours = pa_m::dh_hour(gst2);
186 let gst_minutes = pa_m::dh_min(gst2);
187 let gst_seconds = pa_m::dh_sec(gst2);
188
189 return (gst_hours, gst_minutes, gst_seconds);
190}
191
192pub fn greenwich_sidereal_time_to_universal_time(
197 gst_hours: f64,
198 gst_minutes: f64,
199 gst_seconds: f64,
200 gw_day: f64,
201 gw_month: u32,
202 gw_year: u32,
203) -> (u32, u32, f64, String) {
204 let jd = pa_m::cd_jd(gw_day, gw_month, gw_year);
205 let s = jd - 2451545.0;
206 let t = s / 36525.0;
207 let t01 = 6.697374558 + (2400.051336 * t) + (0.000025862 * t * t);
208 let t02 = t01 - (24.0 * (t01 / 24.0).floor());
209 let gst_hours1 = pa_m::hms_dh(gst_hours, gst_minutes, gst_seconds);
210
211 let a = gst_hours1 - t02;
212 let b = a - (24.0 * (a / 24.0).floor());
213 let ut = b * 0.9972695663;
214 let ut_hours = pa_m::dh_hour(ut);
215 let ut_minutes = pa_m::dh_min(ut);
216 let ut_seconds = pa_m::dh_sec(ut);
217
218 let warning_flag = if ut < 0.065574 { "Warning" } else { "OK" };
219
220 return (ut_hours, ut_minutes, ut_seconds, warning_flag.to_string());
221}
222
223pub fn greenwich_sidereal_time_to_local_sidereal_time(
228 gst_hour: f64,
229 gst_minutes: f64,
230 gst_seconds: f64,
231 geographical_longitude: f64,
232) -> (u32, u32, f64) {
233 let gst = pa_m::hms_dh(gst_hour, gst_minutes, gst_seconds);
234 let offset = geographical_longitude / 15.0;
235 let lst_hours1 = gst + offset;
236 let lst_hours2 = lst_hours1 - (24.0 * (lst_hours1 / 24.0).floor());
237
238 let lst_hours = pa_m::dh_hour(lst_hours2);
239 let lst_minutes = pa_m::dh_min(lst_hours2);
240 let lst_seconds = pa_m::dh_sec(lst_hours2);
241
242 return (lst_hours, lst_minutes, lst_seconds);
243}
244
245pub fn local_sidereal_time_to_greenwich_sidereal_time(
250 lst_hours: f64,
251 lst_minutes: f64,
252 lst_seconds: f64,
253 geographical_longitude: f64,
254) -> (u32, u32, f64) {
255 let gst = pa_m::hms_dh(lst_hours, lst_minutes, lst_seconds);
256 let long_hours = geographical_longitude / 15.0;
257 let gst1 = gst - long_hours;
258 let gst2 = gst1 - (24.0 * (gst1 / 24.0).floor());
259
260 let gst_hours = pa_m::dh_hour(gst2);
261 let gst_minutes = pa_m::dh_min(gst2);
262 let gst_seconds = pa_m::dh_sec(gst2);
263
264 return (gst_hours, gst_minutes, gst_seconds);
265}