practical_astronomy_rust/
moon.rs

1use crate::macros as pa_m;
2use crate::util as pa_u;
3
4/// Calculate approximate position of the Moon.
5///
6/// ## Arguments
7/// * `lct_hour` -- Local civil time, in hours.
8/// * `lct_min` -- Local civil time, in minutes.
9/// * `lct_sec` -- Local civil time, in seconds.
10/// * `is_daylight_saving` -- Is daylight savings in effect?
11/// * `zone_correction_hours` -- Time zone correction, in hours.
12/// * `local_date_day` -- Local date, day part.
13/// * `local_date_month` -- Local date, month part.
14/// * `local_date_year` -- Local date, year part.
15///
16/// ## Returns
17/// * `moon_ra_hour` -- Right ascension of Moon (hour part)
18/// * `moon_ra_min` -- Right ascension of Moon (minutes part)
19/// * `moon_ra_sec` -- Right ascension of Moon (seconds part)
20/// * `moon_dec_deg` -- Declination of Moon (degrees part)
21/// * `moon_dec_min` -- Declination of Moon (minutes part)
22/// * `moon_dec_sec` -- Declination of Moon (seconds part)
23pub fn approximate_position_of_moon(
24    lct_hour: f64,
25    lct_min: f64,
26    lct_sec: f64,
27    is_daylight_saving: bool,
28    zone_correction_hours: i32,
29    local_date_day: f64,
30    local_date_month: u32,
31    local_date_year: u32,
32) -> (f64, f64, f64, f64, f64, f64) {
33    let daylight_saving = if is_daylight_saving == true { 1 } else { 0 };
34
35    let l0 = 91.9293359879052;
36    let p0 = 130.143076320618;
37    let n0 = 291.682546643194;
38    let i: f64 = 5.145396;
39
40    let gdate_day = pa_m::lct_gday(
41        lct_hour,
42        lct_min,
43        lct_sec,
44        daylight_saving,
45        zone_correction_hours,
46        local_date_day,
47        local_date_month,
48        local_date_year,
49    );
50    let gdate_month = pa_m::lct_gmonth(
51        lct_hour,
52        lct_min,
53        lct_sec,
54        daylight_saving,
55        zone_correction_hours,
56        local_date_day,
57        local_date_month,
58        local_date_year,
59    );
60    let gdate_year = pa_m::lct_gyear(
61        lct_hour,
62        lct_min,
63        lct_sec,
64        daylight_saving,
65        zone_correction_hours,
66        local_date_day,
67        local_date_month,
68        local_date_year,
69    );
70
71    let ut_hours = pa_m::lct_ut(
72        lct_hour,
73        lct_min,
74        lct_sec,
75        daylight_saving,
76        zone_correction_hours,
77        local_date_day,
78        local_date_month,
79        local_date_year,
80    );
81    let d_days = pa_m::cd_jd(gdate_day, gdate_month, gdate_year) - pa_m::cd_jd(0.0, 1, 2010)
82        + ut_hours / 24.0;
83    let sun_long_deg = pa_m::sun_long(
84        lct_hour,
85        lct_min,
86        lct_sec,
87        daylight_saving,
88        zone_correction_hours,
89        local_date_day,
90        local_date_month,
91        local_date_year,
92    );
93    let sun_mean_anomaly_rad = pa_m::sun_mean_anomaly(
94        lct_hour,
95        lct_min,
96        lct_sec,
97        daylight_saving,
98        zone_correction_hours,
99        local_date_day,
100        local_date_month,
101        local_date_year,
102    );
103    let lm_deg = pa_m::unwind_deg(13.1763966 * d_days + l0);
104    let mm_deg = pa_m::unwind_deg(lm_deg - 0.1114041 * d_days - p0);
105    let n_deg = pa_m::unwind_deg(n0 - (0.0529539 * d_days));
106    let ev_deg = 1.2739 * ((2.0 * (lm_deg - sun_long_deg) - mm_deg).to_radians()).sin();
107    let ae_deg = 0.1858 * (sun_mean_anomaly_rad).sin();
108    let a3_deg = 0.37 * (sun_mean_anomaly_rad).sin();
109    let mmd_deg = mm_deg + ev_deg - ae_deg - a3_deg;
110    let ec_deg = 6.2886 * mmd_deg.to_radians().sin();
111    let a4_deg = 0.214 * (2.0 * (mmd_deg).to_radians()).sin();
112    let ld_deg = lm_deg + ev_deg + ec_deg - ae_deg + a4_deg;
113    let v_deg = 0.6583 * (2.0 * (ld_deg - sun_long_deg).to_radians()).sin();
114    let ldd_deg = ld_deg + v_deg;
115    let nd_deg = n_deg - 0.16 * (sun_mean_anomaly_rad).sin();
116    let y = ((ldd_deg - nd_deg).to_radians()).sin() * i.to_radians().cos();
117    let x = (ldd_deg - nd_deg).to_radians().cos();
118
119    let moon_long_deg = pa_m::unwind_deg(pa_m::degrees(y.atan2(x)) + nd_deg);
120    let moon_lat_deg =
121        pa_m::degrees(((ldd_deg - nd_deg).to_radians().sin() * i.to_radians().sin()).asin());
122    let moon_ra_hours1 = pa_m::dd_dh(pa_m::ec_ra(
123        moon_long_deg,
124        0.0,
125        0.0,
126        moon_lat_deg,
127        0.0,
128        0.0,
129        gdate_day,
130        gdate_month,
131        gdate_year,
132    ));
133    let moon_dec_deg1 = pa_m::ec_dec(
134        moon_long_deg,
135        0.0,
136        0.0,
137        moon_lat_deg,
138        0.0,
139        0.0,
140        gdate_day,
141        gdate_month,
142        gdate_year,
143    );
144
145    let moon_ra_hour = pa_m::dh_hour(moon_ra_hours1);
146    let moon_ra_min = pa_m::dh_min(moon_ra_hours1);
147    let moon_ra_sec = pa_m::dh_sec(moon_ra_hours1);
148    let moon_dec_deg = pa_m::dd_deg(moon_dec_deg1);
149    let moon_dec_min = pa_m::dd_min(moon_dec_deg1);
150    let moon_dec_sec = pa_m::dd_sec(moon_dec_deg1);
151
152    return (
153        moon_ra_hour as f64,
154        moon_ra_min as f64,
155        moon_ra_sec,
156        moon_dec_deg,
157        moon_dec_min,
158        moon_dec_sec,
159    );
160}
161
162/// Calculate approximate position of the Moon.
163///
164/// ## Arguments
165/// * `lct_hour` -- Local civil time, in hours.
166/// * `lct_min` -- Local civil time, in minutes.
167/// * `lct_sec` -- Local civil time, in seconds.
168/// * `is_daylight_saving` -- Is daylight savings in effect?
169/// * `zone_correction_hours` -- Time zone correction, in hours.
170/// * `local_date_day` -- Local date, day part.
171/// * `local_date_month` -- Local date, month part.
172/// * `local_date_year` -- Local date, year part.
173///
174/// ## Returns
175/// * `moon_ra_hour` -- Right ascension of Moon (hour part)
176/// * `moon_ra_min` -- Right ascension of Moon (minutes part)
177/// * `moon_ra_sec` -- Right ascension of Moon (seconds part)
178/// * `moon_dec_deg` -- Declination of Moon (degrees part)
179/// * `moon_dec_min` -- Declination of Moon (minutes part)
180/// * `moon_dec_sec` -- Declination of Moon (seconds part)
181/// * `earth_moon_dist_km` -- Distance from Earth to Moon (km)
182/// * `moon_hor_parallax_deg` -- Horizontal parallax of Moon (degrees)
183pub fn precise_position_of_moon(
184    lct_hour: f64,
185    lct_min: f64,
186    lct_sec: f64,
187    is_daylight_saving: bool,
188    zone_correction_hours: i32,
189    local_date_day: f64,
190    local_date_month: u32,
191    local_date_year: u32,
192) -> (f64, f64, f64, f64, f64, f64, f64, f64) {
193    let daylight_saving = if is_daylight_saving == true { 1 } else { 0 };
194
195    let gdate_day = pa_m::lct_gday(
196        lct_hour,
197        lct_min,
198        lct_sec,
199        daylight_saving,
200        zone_correction_hours,
201        local_date_day,
202        local_date_month,
203        local_date_year,
204    );
205    let gdate_month = pa_m::lct_gmonth(
206        lct_hour,
207        lct_min,
208        lct_sec,
209        daylight_saving,
210        zone_correction_hours,
211        local_date_day,
212        local_date_month,
213        local_date_year,
214    );
215    let gdate_year = pa_m::lct_gyear(
216        lct_hour,
217        lct_min,
218        lct_sec,
219        daylight_saving,
220        zone_correction_hours,
221        local_date_day,
222        local_date_month,
223        local_date_year,
224    );
225
226    let _ut_hours = pa_m::lct_ut(
227        lct_hour,
228        lct_min,
229        lct_sec,
230        daylight_saving,
231        zone_correction_hours,
232        local_date_day,
233        local_date_month,
234        local_date_year,
235    );
236
237    let (moon_ecliptic_longitude_deg, moon_ecliptic_latitude_deg, moon_horizontal_parallax_deg) =
238        pa_m::moon_long_lat_hp(
239            lct_hour,
240            lct_min,
241            lct_sec,
242            daylight_saving,
243            zone_correction_hours,
244            local_date_day,
245            local_date_month,
246            local_date_year,
247        );
248
249    let nutation_in_longitude_deg = pa_m::nutat_long(gdate_day, gdate_month, gdate_year);
250    let corrected_long_deg = moon_ecliptic_longitude_deg + nutation_in_longitude_deg;
251    let earth_moon_distance_km = 6378.14 / moon_horizontal_parallax_deg.to_radians().sin();
252    let moon_ra_hours_1 = pa_m::dd_dh(pa_m::ec_ra(
253        corrected_long_deg,
254        0.0,
255        0.0,
256        moon_ecliptic_latitude_deg,
257        0.0,
258        0.0,
259        gdate_day,
260        gdate_month,
261        gdate_year,
262    ));
263    let moon_dec_deg1 = pa_m::ec_dec(
264        corrected_long_deg,
265        0.0,
266        0.0,
267        moon_ecliptic_latitude_deg,
268        0.0,
269        0.0,
270        gdate_day,
271        gdate_month,
272        gdate_year,
273    );
274
275    let moon_ra_hour = pa_m::dh_hour(moon_ra_hours_1);
276    let moon_ra_min = pa_m::dh_min(moon_ra_hours_1);
277    let moon_ra_sec = pa_m::dh_sec(moon_ra_hours_1);
278    let moon_dec_deg = pa_m::dd_deg(moon_dec_deg1);
279    let moon_dec_min = pa_m::dd_min(moon_dec_deg1);
280    let moon_dec_sec = pa_m::dd_sec(moon_dec_deg1);
281    let earth_moon_dist_km = pa_u::round_f64(earth_moon_distance_km, 0);
282    let moon_hor_parallax_deg = pa_u::round_f64(moon_horizontal_parallax_deg, 6);
283
284    return (
285        moon_ra_hour as f64,
286        moon_ra_min as f64,
287        moon_ra_sec,
288        moon_dec_deg,
289        moon_dec_min,
290        moon_dec_sec,
291        earth_moon_dist_km,
292        moon_hor_parallax_deg,
293    );
294}
295
296/// Calculate Moon phase and position angle of bright limb.
297///
298/// ## Arguments
299/// * `lct_hour` -- Local civil time, in hours.
300/// * `lct_min` -- Local civil time, in minutes.
301/// * `lct_sec` -- Local civil time, in seconds.
302/// * `is_daylight_saving` -- Is daylight savings in effect?
303/// * `zone_correction_hours` -- Time zone correction, in hours.
304/// * `local_date_day` -- Local date, day part.
305/// * `local_date_month` -- Local date, month part.
306/// * `local_date_year` -- Local date, year part.
307/// * `accuracy_level` -- "A" (approximate) or "P" (precise)
308///
309/// ## Returns
310/// * `moon_phase` -- Phase of Moon, between 0 and 1, where 0 is New and 1 is Full.
311/// * `pa_bright_limb_deg` -- Position angle of the bright limb (degrees)
312pub fn moon_phase(
313    lct_hour: f64,
314    lct_min: f64,
315    lct_sec: f64,
316    is_daylight_saving: bool,
317    zone_correction_hours: i32,
318    local_date_day: f64,
319    local_date_month: u32,
320    local_date_year: u32,
321    accuracy_level: String,
322) -> (f64, f64) {
323    let daylight_saving = if is_daylight_saving == true { 1 } else { 0 };
324
325    let gdate_day = pa_m::lct_gday(
326        lct_hour,
327        lct_min,
328        lct_sec,
329        daylight_saving,
330        zone_correction_hours,
331        local_date_day,
332        local_date_month,
333        local_date_year,
334    );
335    let gdate_month = pa_m::lct_gmonth(
336        lct_hour,
337        lct_min,
338        lct_sec,
339        daylight_saving,
340        zone_correction_hours,
341        local_date_day,
342        local_date_month,
343        local_date_year,
344    );
345    let gdate_year = pa_m::lct_gyear(
346        lct_hour,
347        lct_min,
348        lct_sec,
349        daylight_saving,
350        zone_correction_hours,
351        local_date_day,
352        local_date_month,
353        local_date_year,
354    );
355
356    let sun_long_deg = pa_m::sun_long(
357        lct_hour,
358        lct_min,
359        lct_sec,
360        daylight_saving,
361        zone_correction_hours,
362        local_date_day,
363        local_date_month,
364        local_date_year,
365    );
366    let (moon_ecliptic_longitude_deg, moon_ecliptic_latitude_deg, _moon_horizontal_parallax_deg) =
367        pa_m::moon_long_lat_hp(
368            lct_hour,
369            lct_min,
370            lct_sec,
371            daylight_saving,
372            zone_correction_hours,
373            local_date_day,
374            local_date_month,
375            local_date_year,
376        );
377    let d_rad = (moon_ecliptic_longitude_deg - sun_long_deg).to_radians();
378
379    let moon_phase1 = if accuracy_level.to_string() == "P" {
380        pa_m::moon_phase(
381            lct_hour,
382            lct_min,
383            lct_sec,
384            daylight_saving,
385            zone_correction_hours,
386            local_date_day,
387            local_date_month,
388            local_date_year,
389        )
390    } else {
391        (1.0 - (d_rad).cos()) / 2.0
392    };
393
394    let sun_ra_rad = (pa_m::ec_ra(
395        sun_long_deg,
396        0.0,
397        0.0,
398        0.0,
399        0.0,
400        0.0,
401        gdate_day,
402        gdate_month,
403        gdate_year,
404    ))
405    .to_radians();
406    let moon_ra_rad = (pa_m::ec_ra(
407        moon_ecliptic_longitude_deg,
408        0.0,
409        0.0,
410        moon_ecliptic_latitude_deg,
411        0.0,
412        0.0,
413        gdate_day,
414        gdate_month,
415        gdate_year,
416    ))
417    .to_radians();
418    let sun_dec_rad = (pa_m::ec_dec(
419        sun_long_deg,
420        0.0,
421        0.0,
422        0.0,
423        0.0,
424        0.0,
425        gdate_day,
426        gdate_month,
427        gdate_year,
428    ))
429    .to_radians();
430    let moon_dec_rad = (pa_m::ec_dec(
431        moon_ecliptic_longitude_deg,
432        0.0,
433        0.0,
434        moon_ecliptic_latitude_deg,
435        0.0,
436        0.0,
437        gdate_day,
438        gdate_month,
439        gdate_year,
440    ))
441    .to_radians();
442
443    let y = (sun_dec_rad).cos() * (sun_ra_rad - moon_ra_rad).sin();
444    let x = (moon_dec_rad).cos() * (sun_dec_rad).sin()
445        - (moon_dec_rad).sin() * (sun_dec_rad).cos() * (sun_ra_rad - moon_ra_rad).cos();
446
447    let chi_deg = pa_m::degrees(y.atan2(x));
448
449    let moon_phase = pa_u::round_f64(moon_phase1, 2);
450    let pa_bright_limb_deg = pa_u::round_f64(chi_deg, 2);
451
452    return (moon_phase, pa_bright_limb_deg);
453}
454
455/// Calculate new moon and full moon instances.
456///
457/// ## Arguments
458/// * `is_daylight_saving` -- Is daylight savings in effect?
459/// * `zone_correction_hours` -- Time zone correction, in hours.
460/// * `local_date_day` -- Local date, day part.
461/// * `local_date_month` -- Local date, month part.
462/// * `local_date_year` -- Local date, year part.
463///
464/// ## Returns
465/// * `nm_local_time_hour` -- new Moon instant - local time (hour)
466/// * `nm_local_time_min` -- new Moon instant - local time (minutes)
467/// * `nm_local_date_day` -- new Moon instance - local date (day)
468/// * `nm_local_date_month` -- new Moon instance - local date (month)
469/// * `nm_local_date_year` -- new Moon instance - local date (year)
470/// * `fm_local_time_hour` -- full Moon instant - local time (hour)
471/// * `fm_local_time_min` -- full Moon instant - local time (minutes)
472/// * `fm_local_date_day` -- full Moon instance - local date (day)
473/// * `fm_local_date_month` -- full Moon instance - local date (month)
474/// * `fm_local_date_year` -- full Moon instance - local date (year)
475pub fn times_of_new_moon_and_full_moon(
476    is_daylight_saving: bool,
477    zone_correction_hours: i32,
478    local_date_day: f64,
479    local_date_month: u32,
480    local_date_year: u32,
481) -> (f64, f64, f64, u32, u32, f64, f64, f64, u32, u32) {
482    let daylight_saving = if is_daylight_saving == true { 1 } else { 0 };
483
484    let jd_of_new_moon_days = pa_m::new_moon(
485        daylight_saving,
486        zone_correction_hours,
487        local_date_day,
488        local_date_month,
489        local_date_year,
490    );
491    let jd_of_full_moon_days = pa_m::full_moon(
492        3,
493        zone_correction_hours,
494        local_date_day,
495        local_date_month,
496        local_date_year,
497    );
498
499    let g_date_of_new_moon_day = pa_m::jdc_day(jd_of_new_moon_days);
500    let integer_day1 = g_date_of_new_moon_day.floor();
501    let g_date_of_new_moon_month = pa_m::jdc_month(jd_of_new_moon_days);
502    let g_date_of_new_moon_year = pa_m::jdc_year(jd_of_new_moon_days);
503
504    let g_date_of_full_moon_day = pa_m::jdc_day(jd_of_full_moon_days);
505    let integer_day2 = g_date_of_full_moon_day.floor();
506    let g_date_of_full_moon_month = pa_m::jdc_month(jd_of_full_moon_days);
507    let g_date_of_full_moon_year = pa_m::jdc_year(jd_of_full_moon_days);
508
509    let ut_of_new_moon_hours = 24.0 * (g_date_of_new_moon_day - integer_day1);
510    let ut_of_full_moon_hours = 24.0 * (g_date_of_full_moon_day - integer_day2);
511    let lct_of_new_moon_hours = pa_m::ut_lct(
512        ut_of_new_moon_hours + 0.008333,
513        0.0,
514        0.0,
515        daylight_saving,
516        zone_correction_hours,
517        integer_day1,
518        g_date_of_new_moon_month,
519        g_date_of_new_moon_year,
520    );
521    let lct_of_full_moon_hours = pa_m::ut_lct(
522        ut_of_full_moon_hours + 0.008333,
523        0.0,
524        0.0,
525        daylight_saving,
526        zone_correction_hours,
527        integer_day2,
528        g_date_of_full_moon_month,
529        g_date_of_full_moon_year,
530    );
531
532    let nm_local_time_hour = pa_m::dh_hour(lct_of_new_moon_hours);
533    let nm_local_time_min = pa_m::dh_min(lct_of_new_moon_hours);
534    let nm_local_date_day = pa_m::ut_lc_day(
535        ut_of_new_moon_hours,
536        0.0,
537        0.0,
538        daylight_saving,
539        zone_correction_hours,
540        integer_day1,
541        g_date_of_new_moon_month,
542        g_date_of_new_moon_year,
543    );
544    let nm_local_date_month = pa_m::ut_lc_month(
545        ut_of_new_moon_hours,
546        0.0,
547        0.0,
548        daylight_saving,
549        zone_correction_hours,
550        integer_day1,
551        g_date_of_new_moon_month,
552        g_date_of_new_moon_year,
553    );
554    let nm_local_date_year = pa_m::ut_lc_year(
555        ut_of_new_moon_hours,
556        0.0,
557        0.0,
558        daylight_saving,
559        zone_correction_hours,
560        integer_day1,
561        g_date_of_new_moon_month,
562        g_date_of_new_moon_year,
563    );
564    let fm_local_time_hour = pa_m::dh_hour(lct_of_full_moon_hours);
565    let fm_local_time_min = pa_m::dh_min(lct_of_full_moon_hours);
566    let fm_local_date_day = pa_m::ut_lc_day(
567        ut_of_full_moon_hours,
568        0.0,
569        0.0,
570        daylight_saving,
571        zone_correction_hours,
572        integer_day2,
573        g_date_of_full_moon_month,
574        g_date_of_full_moon_year,
575    );
576    let fm_local_date_month = pa_m::ut_lc_month(
577        ut_of_full_moon_hours,
578        0.0,
579        0.0,
580        daylight_saving,
581        zone_correction_hours,
582        integer_day2,
583        g_date_of_full_moon_month,
584        g_date_of_full_moon_year,
585    );
586    let fm_local_date_year = pa_m::ut_lc_year(
587        ut_of_full_moon_hours,
588        0.0,
589        0.0,
590        daylight_saving,
591        zone_correction_hours,
592        integer_day2,
593        g_date_of_full_moon_month,
594        g_date_of_full_moon_year,
595    );
596
597    return (
598        nm_local_time_hour as f64,
599        nm_local_time_min as f64,
600        nm_local_date_day,
601        nm_local_date_month,
602        nm_local_date_year,
603        fm_local_time_hour as f64,
604        fm_local_time_min as f64,
605        fm_local_date_day,
606        fm_local_date_month,
607        fm_local_date_year,
608    );
609}
610
611/// Calculate Moon's distance, angular diameter, and horizontal parallax.
612///
613/// ## Arguments
614/// * `lct_hour` -- Local civil time, in hours.
615/// * `lct_min` -- Local civil time, in minutes.
616/// * `lct_sec` -- Local civil time, in seconds.
617/// * `is_daylight_saving` -- Is daylight savings in effect?
618/// * `zone_correction_hours` -- Time zone correction, in hours.
619/// * `local_date_day` -- Local date, day part.
620/// * `local_date_month` -- Local date, month part.
621/// * `local_date_year` -- Local date, year part.
622///
623/// ## Returns
624/// * `earth_moon_dist` -- Earth-Moon distance (km)
625/// * `ang_diameter_deg` -- Angular diameter (degrees part)
626/// * `ang_diameter_min` -- Angular diameter (minutes part)
627/// * `hor_parallax_deg` -- Horizontal parallax (degrees part)
628/// * `hor_parallax_min` -- Horizontal parallax (minutes part)
629/// * `hor_parallax_sec` -- Horizontal parallax (seconds part)
630pub fn moon_dist_ang_diam_hor_parallax(
631    lct_hour: f64,
632    lct_min: f64,
633    lct_sec: f64,
634    is_daylight_saving: bool,
635    zone_correction_hours: i32,
636    local_date_day: f64,
637    local_date_month: u32,
638    local_date_year: u32,
639) -> (f64, f64, f64, f64, f64, f64) {
640    let daylight_saving = if is_daylight_saving == true { 1 } else { 0 };
641
642    let moon_distance = pa_m::moon_dist(
643        lct_hour,
644        lct_min,
645        lct_sec,
646        daylight_saving,
647        zone_correction_hours,
648        local_date_day,
649        local_date_month,
650        local_date_year,
651    );
652    let moon_angular_diameter = pa_m::moon_size(
653        lct_hour,
654        lct_min,
655        lct_sec,
656        daylight_saving,
657        zone_correction_hours,
658        local_date_day,
659        local_date_month,
660        local_date_year,
661    );
662    let moon_horizontal_parallax = pa_m::moon_hp(
663        lct_hour,
664        lct_min,
665        lct_sec,
666        daylight_saving,
667        zone_correction_hours,
668        local_date_day,
669        local_date_month,
670        local_date_year,
671    );
672
673    // earth_moon_dist = round(moon_distance,-1)
674    let earth_moon_dist = pa_u::round_f64(moon_distance, 0);
675    let ang_diameter_deg = pa_m::dd_deg(moon_angular_diameter + 0.008333);
676    let ang_diameter_min = pa_m::dd_min(moon_angular_diameter + 0.008333);
677    let hor_parallax_deg = pa_m::dd_deg(moon_horizontal_parallax);
678    let hor_parallax_min = pa_m::dd_min(moon_horizontal_parallax);
679    let hor_parallax_sec = pa_m::dd_sec(moon_horizontal_parallax);
680
681    return (
682        earth_moon_dist,
683        ang_diameter_deg,
684        ang_diameter_min,
685        hor_parallax_deg,
686        hor_parallax_min,
687        hor_parallax_sec,
688    );
689}
690
691/// Calculate date/time of local moonrise and moonset.
692///
693/// ## Arguments
694/// * `local_date_day` -- Local date, day part.
695/// * `local_date_month` -- Local date, month part.
696/// * `local_date_year` -- Local date, year part.
697/// * `is_daylight_saving` -- Is daylight savings in effect?
698/// * `zone_correction_hours` -- Time zone correction, in hours.
699/// * `geog_long_deg` -- Geographical longitude, in degrees.
700/// * `geog_lat_deg` -- Geographical latitude, in degrees.
701///
702/// ## Returns
703/// * `mr_lt_hour` -- Moonrise, local time (hour part)
704/// * `mr_lt_min` -- Moonrise, local time (minutes part)
705/// * `mr_local_date_day` -- Moonrise, local date (day)
706/// * `mr_local_date_month` -- Moonrise, local date (month)
707/// * `mr_local_date_year` -- Moonrise, local date (year)
708/// * `mr_azimuth_deg` -- Moonrise, azimuth (degrees)
709/// * `ms_lt_hour` -- Moonset, local time (hour part)
710/// * `ms_lt_min` -- Moonset, local time (minutes part)
711/// * `ms_local_date_day` -- Moonset, local date (day)
712/// * `ms_local_date_month` -- Moonset, local date (month)
713/// * `ms_local_date_year` -- Moonset, local date (year)
714/// * `ms_azimuth_deg` -- Moonset, azimuth (degrees)
715pub fn moonrise_and_moonset(
716    local_date_day: f64,
717    local_date_month: u32,
718    local_date_year: u32,
719    is_daylight_saving: bool,
720    zone_correction_hours: i32,
721    geog_long_deg: f64,
722    geog_lat_deg: f64,
723) -> (f64, f64, f64, u32, u32, f64, f64, f64, f64, u32, u32, f64) {
724    let daylight_saving = if is_daylight_saving == true { 1 } else { 0 };
725
726    let local_time_of_moonrise_hours = pa_m::moon_rise_lct(
727        local_date_day,
728        local_date_month,
729        local_date_year,
730        daylight_saving,
731        zone_correction_hours,
732        geog_long_deg,
733        geog_lat_deg,
734    );
735    let _local_moonrise_status1 = pa_m::e_moon_rise(
736        local_date_day,
737        local_date_month,
738        local_date_year,
739        daylight_saving,
740        zone_correction_hours,
741        geog_long_deg,
742        geog_lat_deg,
743    );
744    let (local_date_of_moonrise_day, local_date_of_moonrise_month, local_date_of_moonrise_year) =
745        pa_m::moon_rise_lc_dmy(
746            local_date_day,
747            local_date_month,
748            local_date_year,
749            daylight_saving,
750            zone_correction_hours,
751            geog_long_deg,
752            geog_lat_deg,
753        );
754    let local_azimuth_deg1 = pa_m::moon_rise_az(
755        local_date_day,
756        local_date_month,
757        local_date_year,
758        daylight_saving,
759        zone_correction_hours,
760        geog_long_deg,
761        geog_lat_deg,
762    );
763
764    let local_time_of_moonset_hours = pa_m::moon_set_lct(
765        local_date_day,
766        local_date_month,
767        local_date_year,
768        daylight_saving,
769        zone_correction_hours,
770        geog_long_deg,
771        geog_lat_deg,
772    );
773    let _local_moonset_status1 = pa_m::e_moon_set(
774        local_date_day,
775        local_date_month,
776        local_date_year,
777        daylight_saving,
778        zone_correction_hours,
779        geog_long_deg,
780        geog_lat_deg,
781    );
782    let (local_date_of_moonset_day, local_date_of_moonset_month, local_date_of_moonset_year) =
783        pa_m::moon_set_lc_dmy(
784            local_date_day,
785            local_date_month,
786            local_date_year,
787            daylight_saving,
788            zone_correction_hours,
789            geog_long_deg,
790            geog_lat_deg,
791        );
792    let local_azimuth_deg2 = pa_m::moon_set_az(
793        local_date_day,
794        local_date_month,
795        local_date_year,
796        daylight_saving,
797        zone_correction_hours,
798        geog_long_deg,
799        geog_lat_deg,
800    );
801
802    let mr_lt_hour = pa_m::dh_hour(local_time_of_moonrise_hours + 0.008333);
803    let mr_lt_min = pa_m::dh_min(local_time_of_moonrise_hours + 0.008333);
804    let mr_local_date_day = local_date_of_moonrise_day;
805    let mr_local_date_month = local_date_of_moonrise_month;
806    let mr_local_date_year = local_date_of_moonrise_year;
807    let mr_azimuth_deg = pa_u::round_f64(local_azimuth_deg1, 2);
808    let ms_lt_hour = pa_m::dh_hour(local_time_of_moonset_hours + 0.008333);
809    let ms_lt_min = pa_m::dh_min(local_time_of_moonset_hours + 0.008333);
810    let ms_local_date_day = local_date_of_moonset_day;
811    let ms_local_date_month = local_date_of_moonset_month;
812    let ms_local_date_year = local_date_of_moonset_year;
813    let ms_azimuth_deg = pa_u::round_f64(local_azimuth_deg2, 2);
814
815    return (
816        mr_lt_hour as f64,
817        mr_lt_min as f64,
818        mr_local_date_day,
819        mr_local_date_month,
820        mr_local_date_year,
821        mr_azimuth_deg,
822        ms_lt_hour as f64,
823        ms_lt_min as f64,
824        ms_local_date_day,
825        ms_local_date_month,
826        ms_local_date_year,
827        ms_azimuth_deg,
828    );
829}