File Coverage

lib/Astro/Montenbruck/SolEqu.pm
Criterion Covered Total %
statement 47 47 100.0
branch 1 2 50.0
condition 2 3 66.6
subroutine 11 11 100.0
pod 1 1 100.0
total 62 64 96.8


line stmt bran cond sub pod time code
1             package Astro::Montenbruck::SolEqu;
2              
3 1     1   93268 use strict;
  1         10  
  1         25  
4 1     1   4 use warnings;
  1         2  
  1         22  
5              
6 1     1   4 use Exporter qw/import/;
  1         2  
  1         45  
7 1     1   442 use Readonly;
  1         3390  
  1         46  
8 1     1   432 use Math::Trig qw/deg2rad/;
  1         13564  
  1         70  
9 1     1   409 use Astro::Montenbruck::MathUtils qw/angle_c/;
  1         3  
  1         63  
10 1     1   397 use Astro::Montenbruck::Time::DeltaT qw/delta_t/;
  1         3  
  1         50  
11 1     1   6 use Astro::Montenbruck::Time qw/jd_cent $SEC_PER_DAY/;
  1         2  
  1         80  
12 1     1   451 use Astro::Montenbruck::Ephemeris::Planet::Sun;
  1         2  
  1         44  
13 1     1   346 use Astro::Montenbruck::NutEqu qw/mean2true/;
  1         2  
  1         373  
14              
15              
16             Readonly our $MARCH_EQUINOX => 0;
17             Readonly our $JUNE_SOLSTICE => 1;
18             Readonly our $SEPTEMBER_EQUINOX => 2;
19             Readonly our $DECEMBER_SOLSTICE => 3;
20              
21             Readonly my $DELTA => 1e-4;
22              
23             Readonly::Array our @SOLEQU_EVENTS => ($MARCH_EQUINOX, $JUNE_SOLSTICE, $SEPTEMBER_EQUINOX, $DECEMBER_SOLSTICE);
24             our @CONSTS = qw/$MARCH_EQUINOX $JUNE_SOLSTICE $SEPTEMBER_EQUINOX $DECEMBER_SOLSTICE @SOLEQU_EVENTS/;
25              
26             our %EXPORT_TAGS = (
27             events => \@CONSTS,
28             all => [ @CONSTS, 'solequ' ]
29             );
30             our @EXPORT_OK = ( @{ $EXPORT_TAGS{all} } );
31              
32             our $VERSION = 0.02;
33              
34             sub solequ {
35 6     6 1 5204 my ($year, $k) = @_;
36              
37             # find approximate time in Julian Days
38             # k = 0 for March equinox,
39             # 1 for the Julne solstice
40             # 2 for the September equinox
41             # 3 for the December solstice
42             # print("k = $k, year = $year\n");
43 6         17 my $j = ($year + $k / 4) * 365.2422 + 1721141.3;
44             # print("j = $j\n");
45 6         11 my $k90 = $k * 90;
46 6         20 my $sun = Astro::Montenbruck::Ephemeris::Planet::Sun->new();
47 6         15 my $nut_func = mean2true(jd_cent($j));
48 6         9 my $x = -1000;
49 6         9 my $last_x;
50 6   66     7 do {
51 23         121 $last_x = $x;
52 23         52 my $t = jd_cent($j);
53 23         52 my @lbr = $sun->sunpos($t);
54 23         266 my $nut_func = mean2true($t);
55 23         58 ($x) = $sun->apparent($t, \@lbr, $nut_func); # apparent geocentric ecliptical coordinates
56 23         254 $j += 58 * sin(deg2rad($k90 - $x));
57             # print("j = $j, x = $x, last_x = $last_x\n")
58             } until(angle_c($k90, $x) < $DELTA || $x == $last_x);
59              
60 6         40 my $dt = delta_t($j);
61 6         11 $j -= $dt / $SEC_PER_DAY;
62 6 50       38 wantarray ? ($j, $x) : $j
63             }
64              
65             1;
66             __END__
67              
68              
69             =pod
70              
71             =encoding UTF-8
72              
73             =head1 NAME
74              
75             Astro::Montenbruck::SolEqu - Solstices and Equinoxes.
76              
77             =head1 SYNOPSIS
78              
79             use Astro::Montenbruck::SolEqu qw/:all/;
80              
81             # find solstices and equinoxes for year 2020
82             for my $event (@SOLEQU_EVENTS)
83             {
84             my $jd = solequ(2020, $event);
85             # ...
86             }
87              
88              
89             =head1 DESCRIPTION
90              
91             The times of he equinoxes and solstices are the instants when the apparent longiude
92             of the Sun is a multiple of B<90 degrees>.
93              
94             Searches solstices and eqinoxes. Algorithms are based on
95             I<"Astronomical Formulae for Calculators"> by I<Jean Meeus>, I<Forth Edition>, I<Willmann-Bell, Inc., 1988>.
96              
97              
98             =head1 EXPORT
99              
100             =head2 CONSTANTS
101              
102             =head3 EVENTS
103              
104             =over
105              
106             =item * C<$MARCH_EQUINOX>
107              
108             =item * C<$JUNE_SOLSTICE>
109              
110             =item * C<$SEPTEMBER_EQUINOX>
111              
112             =item * C<$DECEMBER_SOLSTICE>
113              
114             =back
115              
116             =head3 ARRAY OF THE EVENTS
117              
118             =over
119              
120             =item * C<@SOLEQU_EVENTS>
121              
122             =back
123              
124             Array of L<EVENTS> in proper order.
125              
126              
127             =head1 SUBROUTINES
128              
129              
130             =head2 solequ
131              
132             Find Julian Day of solstice or equinox for a given year.
133              
134             use Astro::Montenbruck::SolEqu qw/:all/;
135              
136             my $jd = Astro::Montenbruck::Ephemeris::Sun->solequ($year, $k);
137              
138             The result is accurate within I<5 minutes> of Universal Time.
139              
140             =head3 Arguments
141              
142             =over
143              
144             =item 1.
145              
146             number of a year (negative for B.C., astronomical)
147              
148             =item 2.
149              
150             type of event, defined by the constants (see L<Events>).
151              
152             =back
153              
154             =head3 Result
155              
156             In scalar context retuns I<Standard Julian Day>.
157             In list context: array of:
158              
159             =over
160              
161             =item 1.
162              
163             I<Standard Julian Day> and Sun's longitude, in arc-dgrees.
164              
165             =item 2.
166              
167             Sun's longitude, arc-dgrees.
168              
169             =back
170              
171              
172             =head1 AUTHOR
173              
174             Sergey Krushinsky, C<< <krushi at cpan.org> >>
175              
176             =head1 COPYRIGHT AND LICENSE
177              
178             Copyright (C) 2009-2022 by Sergey Krushinsky
179              
180             This library is free software; you can redistribute it and/or modify
181             it under the same terms as Perl itself.
182              
183             =cut