1use crate::macros as pa_m;
2use crate::util as pa_u;
3
4pub 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
162pub 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
296pub 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
455pub 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
611pub 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 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
691pub 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}