line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Astro::Utils; |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
$Astro::Utils::VERSION = '0.05'; |
4
|
|
|
|
|
|
|
$Astro::Utils::AUTHORITY = 'cpan:MANWAR'; |
5
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
=head1 NAME |
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
Astro::Utils - Utility package for Astronomical Calculations. |
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
=head1 VERSION |
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
Version 0.05 |
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
=cut |
15
|
|
|
|
|
|
|
|
16
|
3
|
|
|
3
|
|
206756
|
use 5.006; |
|
3
|
|
|
|
|
26
|
|
17
|
3
|
|
|
3
|
|
13
|
use strict; use warnings; |
|
3
|
|
|
3
|
|
5
|
|
|
3
|
|
|
|
|
70
|
|
|
3
|
|
|
|
|
12
|
|
|
3
|
|
|
|
|
6
|
|
|
3
|
|
|
|
|
79
|
|
18
|
3
|
|
|
3
|
|
1214
|
use Data::Dumper; |
|
3
|
|
|
|
|
17117
|
|
|
3
|
|
|
|
|
234
|
|
19
|
3
|
|
|
3
|
|
1805
|
use DateTime; |
|
3
|
|
|
|
|
1203994
|
|
|
3
|
|
|
|
|
141
|
|
20
|
|
|
|
|
|
|
|
21
|
3
|
|
|
3
|
|
23
|
use parent 'Exporter'; |
|
3
|
|
|
|
|
6
|
|
|
3
|
|
|
|
|
28
|
|
22
|
|
|
|
|
|
|
our @EXPORT = qw(calculate_equinox calculate_solstice); |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
my $PI = 3.141592653589793; |
25
|
|
|
|
|
|
|
my $TYPE = { 'MAR' => 0, 'JUN' => 1, 'SEP' => 2, 'DEC' => 3 }; |
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
=head1 DESCRIPTION |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
The entire algorithm is based on the book "Astronomical Algorithms", 2nd Edition |
30
|
|
|
|
|
|
|
by Jean Meeus,(C)1998, published by Willmann-Bell, Inc. I needed this for one of |
31
|
|
|
|
|
|
|
my disrtribution L<Calendar::Bahai>. |
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
The calculated times are in Terrestrial Dynamical Time (TDT or TT), a replacement |
34
|
|
|
|
|
|
|
for Ephemeris Times(ET).TDT is a uniform time used for astronomical calculations. |
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
=head1 SYNOPSIS |
37
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
use strict; use warnings; |
39
|
|
|
|
|
|
|
use Astro::Utils; |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
print "Mar'2015 Equinox (UTC): ", calculate_equinox ('mar', 'utc', 2015),"\n"; |
42
|
|
|
|
|
|
|
print "Mar'2015 Equinox (TDT): ", calculate_equinox ('mar', 'tdt', 2015),"\n"; |
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
print "Jun'2015 Solstice (UTC): ", calculate_solstice('jun', 'utc', 2015),"\n"; |
45
|
|
|
|
|
|
|
print "Jun'2015 Solstice (TDT): ", calculate_solstice('jun', 'tdt', 2015),"\n"; |
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
print "Sep'2015 Equinox (UTC): ", calculate_equinox ('sep', 'utc', 2015),"\n"; |
48
|
|
|
|
|
|
|
print "Sep'2015 Equinox (TDT): ", calculate_equinox ('sep', 'tdt', 2015),"\n"; |
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
print "Dec'2015 Solstice (UTC): ", calculate_solstice('dec', 'utc', 2015),"\n"; |
51
|
|
|
|
|
|
|
print "Dec'2015 Solstice (TDT): ", calculate_solstice('dec', 'tdt', 2015),"\n"; |
52
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
=head1 METHODS |
54
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
=head2 calculate_equinox($type, $timezone, $year) |
56
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
The param C<$type> can be either 'mar' or 'sep'. The param C<$timezone> can be |
58
|
|
|
|
|
|
|
either 'UTC' or 'TDT'. And finally C<$year> can be anything between -1000 & 3000. |
59
|
|
|
|
|
|
|
All parameters are required. |
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
=cut |
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
sub calculate_equinox { |
64
|
4
|
|
|
4
|
1
|
1315
|
my ($type, $timezone, $year) = @_; |
65
|
|
|
|
|
|
|
|
66
|
4
|
50
|
33
|
|
|
30
|
die "ERROR: Year should be between -1000 and 3000.\n" |
|
|
|
33
|
|
|
|
|
67
|
|
|
|
|
|
|
unless (defined $year && ($year >= -1000) && ($year <= 3000)); |
68
|
|
|
|
|
|
|
|
69
|
4
|
100
|
|
|
|
20
|
if ($timezone =~ /^utc$/i) { |
|
|
50
|
|
|
|
|
|
70
|
2
|
|
|
|
|
10
|
return _calc_utc_equinox($TYPE->{uc($type)}, $year); |
71
|
|
|
|
|
|
|
} |
72
|
|
|
|
|
|
|
elsif ($timezone =~ /^tdt$/i) { |
73
|
2
|
|
|
|
|
9
|
return _calc_tdt_equinox($TYPE->{uc($type)}, $year); |
74
|
|
|
|
|
|
|
} |
75
|
|
|
|
|
|
|
else { |
76
|
0
|
|
|
|
|
0
|
die "ERROR: Invalid timezone [$timezone] received.\n"; |
77
|
|
|
|
|
|
|
} |
78
|
|
|
|
|
|
|
} |
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
=head2 calculate_solstice($type. $timezone, $year) |
81
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
The param C<$type> can be either 'jun' or 'dec'. The param C<$timezone> can be |
83
|
|
|
|
|
|
|
either 'UTC' or 'TDT'. And finally C<$year> can be anything between -1000 & 3000. |
84
|
|
|
|
|
|
|
All parameters are required. |
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
=cut |
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
sub calculate_solstice { |
89
|
4
|
|
|
4
|
1
|
1372
|
my ($type, $timezone, $year) = @_; |
90
|
|
|
|
|
|
|
|
91
|
4
|
50
|
33
|
|
|
28
|
die "ERROR: Year should be between -1000 and 3000.\n" |
|
|
|
33
|
|
|
|
|
92
|
|
|
|
|
|
|
unless (defined $year && ($year >= -1000) && ($year <= 3000)); |
93
|
|
|
|
|
|
|
|
94
|
4
|
100
|
|
|
|
23
|
if ($timezone =~ /^utc$/i) { |
|
|
50
|
|
|
|
|
|
95
|
2
|
|
|
|
|
9
|
return _calc_utc_solstice($TYPE->{uc($type)}, $year); |
96
|
|
|
|
|
|
|
} |
97
|
|
|
|
|
|
|
elsif ($timezone =~ /^tdt$/i) { |
98
|
2
|
|
|
|
|
7
|
return _calc_tdt_solstice($TYPE->{uc($type)}, $year); |
99
|
|
|
|
|
|
|
} |
100
|
|
|
|
|
|
|
else { |
101
|
0
|
|
|
|
|
0
|
die "ERROR: Invalid timezone [$timezone] received.\n"; |
102
|
|
|
|
|
|
|
} |
103
|
|
|
|
|
|
|
} |
104
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
# |
106
|
|
|
|
|
|
|
# |
107
|
|
|
|
|
|
|
# PRIVATE METHODS |
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
sub _calc_utc_equinox { |
110
|
2
|
|
|
2
|
|
4
|
my ($k, $year) = @_; |
111
|
|
|
|
|
|
|
|
112
|
2
|
50
|
33
|
|
|
11
|
die "ERROR: Invalid type for equinox.\n" unless (defined $k && ($k =~ /^[0|2]$/)); |
113
|
2
|
|
|
|
|
7
|
my $jd = _calc_jd($k, $year); |
114
|
2
|
|
|
|
|
6
|
return _jd_to_utc($jd); |
115
|
|
|
|
|
|
|
} |
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
sub _calc_utc_solstice { |
118
|
2
|
|
|
2
|
|
6
|
my ($k, $year) = @_; |
119
|
|
|
|
|
|
|
|
120
|
2
|
50
|
33
|
|
|
12
|
die "ERROR: Invalid type for solstice.\n" unless (defined $k && ($k =~ /^[1|3]$/)); |
121
|
2
|
|
|
|
|
8
|
my $jd = _calc_jd($k, $year); |
122
|
2
|
|
|
|
|
6
|
return _jd_to_utc($jd); |
123
|
|
|
|
|
|
|
} |
124
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
sub _calc_tdt_equinox { |
126
|
2
|
|
|
2
|
|
4
|
my ($k, $year) = @_; |
127
|
|
|
|
|
|
|
|
128
|
2
|
50
|
33
|
|
|
11
|
die "ERROR: Invalid type for equinox.\n" unless (defined $k && ($k =~ /^[0|2]$/)); |
129
|
2
|
|
|
|
|
5
|
my $jd = _calc_jd($k, $year); |
130
|
2
|
|
|
|
|
7
|
return _jd_to_tdt($jd); |
131
|
|
|
|
|
|
|
} |
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
sub _calc_tdt_solstice { |
134
|
2
|
|
|
2
|
|
5
|
my ($k, $year) = @_; |
135
|
|
|
|
|
|
|
|
136
|
2
|
50
|
33
|
|
|
12
|
die "ERROR: Invalid type for solstice.\n" unless (defined $k && ($k =~ /^[1|3]$/)); |
137
|
2
|
|
|
|
|
3
|
my $jd = _calc_jd($k, $year); |
138
|
2
|
|
|
|
|
7
|
return _jd_to_tdt($jd); |
139
|
|
|
|
|
|
|
} |
140
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
sub _calc_jd { |
142
|
8
|
|
|
8
|
|
17
|
my ($k, $year) = @_; |
143
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
# Astronmical Algorithms, Chapter 27. |
145
|
8
|
|
|
|
|
39
|
my $jde0 = _jde0($k, $year); |
146
|
8
|
|
|
|
|
15
|
my $t = ($jde0 - 2451545.0) / 36525; |
147
|
8
|
|
|
|
|
12
|
my $w = 35999.373 * $t - 2.47; |
148
|
8
|
|
|
|
|
17
|
my $dl = 1 + 0.0334 * _cos($w) + 0.0007 * _cos(2 * $w); |
149
|
8
|
|
|
|
|
22
|
my $s = _periodic_term_24($t); |
150
|
|
|
|
|
|
|
|
151
|
8
|
|
|
|
|
19
|
return ($jde0 + ( (0.00001 * $s) / $dl )); |
152
|
|
|
|
|
|
|
} |
153
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
sub _jd_to_utc { |
155
|
4
|
|
|
4
|
|
7
|
my ($jd) = @_; |
156
|
|
|
|
|
|
|
|
157
|
4
|
|
|
|
|
10
|
my ($yr, $mon, $day, $hr, $min, $sec) = _process($jd); |
158
|
|
|
|
|
|
|
|
159
|
4
|
|
|
|
|
30
|
my $date = DateTime->new(year => $yr, month => $mon, day => $day, hour => $hr, minute => $min, second => $sec); |
160
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
# Astronmical Algorithms, Chapter 10, page 79 (Table 10.A). |
162
|
4
|
|
|
|
|
1399
|
my $first = 1620; |
163
|
4
|
|
|
|
|
7
|
my $last = 2002; |
164
|
4
|
|
|
|
|
81
|
my @tbl = (121,112,103,95,88,82,77,72,68,63,60,56,53,51,48,46,44,42,40,38, # 1620 |
165
|
|
|
|
|
|
|
35,33,31,29,26,24,22,20,18,16,14,12,11,10,9,8,7,7,7,7, # 1660 |
166
|
|
|
|
|
|
|
7,7,8,8,9,9,9,9,9,10,10,10,10,10,10,10,10,11,11,11, # 1700 |
167
|
|
|
|
|
|
|
11,11,12,12,12,12,13,13,13,14,14,14,14,15,15,15,15,15,16,16, # 1740 |
168
|
|
|
|
|
|
|
16,16,16,16,16,16,15,15,14,13, # 1780 |
169
|
|
|
|
|
|
|
13.1,12.5,12.2,12.0,12.0,12.0,12.0,12.0,12.0,11.9,11.6,11.0,10.2,9.2,8.2, # 1800 |
170
|
|
|
|
|
|
|
7.1,6.2,5.6,5.4,5.3,5.4,5.6,5.9,6.2,6.5,6.8,7.1,7.3,7.5,7.6, # 1830 |
171
|
|
|
|
|
|
|
7.7,7.3,6.2,5.2,2.7,1.4,-1.2,-2.8,-3.8,-4.8,-5.5,-5.3,-5.6,-5.7,-5.9, # 1860 |
172
|
|
|
|
|
|
|
-6.0,-6.3,-6.5,-6.2,-4.7,-2.8,-0.1,2.6,5.3,7.7,10.4,13.3,16.0,18.2,20.2, # 1890 |
173
|
|
|
|
|
|
|
21.1,22.4,23.5,23.8,24.3,24.0,23.9,23.9,23.7,24.0,24.3,25.3,26.2,27.3,28.2, # 1920 |
174
|
|
|
|
|
|
|
29.1,30.0,30.7,31.4,32.2,33.1,34.0,35.0,36.5,38.3,40.2,42.2,44.5,46.5,48.5, # 1950 |
175
|
|
|
|
|
|
|
50.5,52.5,53.8,54.9,55.8,56.9,58.3,60.0,61.6,63.0,63.8,64.3 # 1980, 2002 last entry |
176
|
|
|
|
|
|
|
); |
177
|
|
|
|
|
|
|
|
178
|
4
|
|
|
|
|
6
|
my $delta_t = 0; |
179
|
4
|
|
|
|
|
10
|
my $t = ($yr - 2000) / 100; |
180
|
|
|
|
|
|
|
|
181
|
4
|
50
|
33
|
|
|
20
|
if ($yr >= $first && $yr <= $last) { |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
182
|
4
|
50
|
|
|
|
12
|
if ($yr % 2) { |
183
|
0
|
|
|
|
|
0
|
$delta_t = ($tbl[($yr - $first - 1) / 2] + $tbl[($yr - $first + 1) / 2] ) / 2; |
184
|
|
|
|
|
|
|
} |
185
|
|
|
|
|
|
|
else { |
186
|
4
|
|
|
|
|
13
|
$delta_t = $tbl[($yr - $first) / 2]; |
187
|
|
|
|
|
|
|
} |
188
|
|
|
|
|
|
|
} elsif ($yr < 948) { |
189
|
0
|
|
|
|
|
0
|
$delta_t = 2177 + 497 * $t + (44.1 * _pow($t, 2)); |
190
|
|
|
|
|
|
|
} elsif ($yr >= 948) { |
191
|
0
|
|
|
|
|
0
|
$delta_t = 102 + 102 * $t + (25.3 * _pow($t, 2)); |
192
|
0
|
0
|
0
|
|
|
0
|
if ($yr >= 2000 && $yr <= 2100) { |
193
|
0
|
|
|
|
|
0
|
$delta_t += 0.37 * ($yr - 2100); |
194
|
|
|
|
|
|
|
} |
195
|
|
|
|
|
|
|
} |
196
|
|
|
|
|
|
|
|
197
|
4
|
|
|
|
|
18
|
$date->subtract(seconds => $delta_t); |
198
|
|
|
|
|
|
|
|
199
|
4
|
|
|
|
|
4366
|
return sprintf("%04d-%02d-%02d %02d:%02d:%02d", |
200
|
|
|
|
|
|
|
$date->year, $date->month, $date->day, $date->hour, $date->minute, $date->second); |
201
|
|
|
|
|
|
|
} |
202
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
sub _jd_to_tdt { |
204
|
4
|
|
|
4
|
|
9
|
my ($jd) = @_; |
205
|
|
|
|
|
|
|
|
206
|
4
|
|
|
|
|
9
|
my ($yr, $mon, $day, $hr, $min, $sec) = _process($jd); |
207
|
4
|
|
|
|
|
34
|
return sprintf("%04d-%02d-%02d %02d:%02d:%02d", $yr, $mon, $day, $hr, $min, $sec); |
208
|
|
|
|
|
|
|
} |
209
|
|
|
|
|
|
|
|
210
|
|
|
|
|
|
|
sub _process { |
211
|
8
|
|
|
8
|
|
13
|
my ($jd) = @_; |
212
|
|
|
|
|
|
|
|
213
|
|
|
|
|
|
|
# Astronmical Algorithms Chapter 7, page 63. |
214
|
8
|
|
|
|
|
11
|
my ($a, $alpha); |
215
|
8
|
|
|
|
|
14
|
my $z = int($jd + 0.5); |
216
|
8
|
|
|
|
|
15
|
my $f = ($jd + 0.5) - $z; |
217
|
|
|
|
|
|
|
|
218
|
8
|
50
|
|
|
|
17
|
if ($z < 2299161) { |
219
|
0
|
|
|
|
|
0
|
$a = $z; |
220
|
|
|
|
|
|
|
} |
221
|
|
|
|
|
|
|
else { |
222
|
8
|
|
|
|
|
14
|
$alpha = int(($z - 1867216.25) / 36524.25); |
223
|
8
|
|
|
|
|
15
|
$a = $z + 1 + $alpha - int($alpha / 4); |
224
|
|
|
|
|
|
|
} |
225
|
|
|
|
|
|
|
|
226
|
8
|
|
|
|
|
14
|
my $b = $a + 1524; |
227
|
8
|
|
|
|
|
12
|
my $c = int(($b - 122.1) / 365.25); |
228
|
8
|
|
|
|
|
13
|
my $d = int(365.25 * $c); |
229
|
8
|
|
|
|
|
13
|
my $e = int(($b -$d) / 30.6001); |
230
|
8
|
|
|
|
|
15
|
my $dt = $b - $d - int(30.6001 * $e) + $f; |
231
|
8
|
50
|
|
|
|
17
|
my $mon = $e - (($e < 13.5)?(1):(13)); |
232
|
8
|
50
|
|
|
|
16
|
my $yr = $c - (($mon > 2.5)?(4716):(4715)); |
233
|
8
|
|
|
|
|
12
|
my $day = int($dt); |
234
|
8
|
|
|
|
|
12
|
my $h = 24 * ($dt - $day); |
235
|
8
|
|
|
|
|
10
|
my $hr = int($h); |
236
|
8
|
|
|
|
|
18
|
my $m = 60 * ($h - $hr); |
237
|
8
|
|
|
|
|
9
|
my $min = int($m); |
238
|
8
|
|
|
|
|
14
|
my $sec = int(60 * ($m - $min)); |
239
|
|
|
|
|
|
|
|
240
|
8
|
|
|
|
|
28
|
return ($yr, $mon, $day, $hr, $min, $sec); |
241
|
|
|
|
|
|
|
} |
242
|
|
|
|
|
|
|
|
243
|
|
|
|
|
|
|
sub _periodic_term_24 { |
244
|
8
|
|
|
8
|
|
12
|
my ($t) = @_; |
245
|
|
|
|
|
|
|
|
246
|
|
|
|
|
|
|
# Astronmical Algorithms, Chapter 27, page 179 (Table 27.C). |
247
|
8
|
|
|
|
|
28
|
my @a = (485,203,199,182,156,136,77,74,70,58,52, |
248
|
|
|
|
|
|
|
50,45,44,29,18,17,16,14,12,12,12,9,8); |
249
|
8
|
|
|
|
|
23
|
my @b = (324.96,337.23,342.08,27.85,73.14,171.52, |
250
|
|
|
|
|
|
|
222.54,296.72,243.58,119.81,297.17,21.02, |
251
|
|
|
|
|
|
|
247.54,325.15,60.93,155.12,288.79,198.04, |
252
|
|
|
|
|
|
|
199.76,95.39,287.11,320.81,227.73,15.45); |
253
|
8
|
|
|
|
|
20
|
my @c = (1934.136,32964.467,20.186,445267.112,45036.886, |
254
|
|
|
|
|
|
|
22518.443,65928.934,3034.906,9037.513, |
255
|
|
|
|
|
|
|
33718.147,150.678,2281.226,29929.562,31555.956, |
256
|
|
|
|
|
|
|
4443.417,67555.328,4562.452,62894.029, |
257
|
|
|
|
|
|
|
31436.921,14577.848,31931.756,34777.259, |
258
|
|
|
|
|
|
|
1222.114,16859.074); |
259
|
|
|
|
|
|
|
|
260
|
8
|
|
|
|
|
11
|
my $s = 0; |
261
|
8
|
|
|
|
|
18
|
foreach my $i (0..23) { |
262
|
192
|
|
|
|
|
282
|
$s += ($a[$i] * _cos($b[$i] + ($c[$i] * $t))); |
263
|
|
|
|
|
|
|
} |
264
|
|
|
|
|
|
|
|
265
|
8
|
|
|
|
|
24
|
return $s; |
266
|
|
|
|
|
|
|
} |
267
|
|
|
|
|
|
|
|
268
|
|
|
|
|
|
|
sub _jde0 { |
269
|
8
|
|
|
8
|
|
15
|
my ($k, $year) = @_; |
270
|
|
|
|
|
|
|
|
271
|
|
|
|
|
|
|
# Julian Ephemeris Day Calculation. |
272
|
8
|
|
|
|
|
46
|
my ($jde0, $y); |
273
|
|
|
|
|
|
|
|
274
|
8
|
50
|
33
|
|
|
48
|
if ($year >= -1000 && $year <= 1000) { |
|
|
50
|
33
|
|
|
|
|
275
|
|
|
|
|
|
|
# Astronmical Algorithms, Chapter 27, page 178 (Table 27.A). |
276
|
0
|
|
|
|
|
0
|
$y = $year / 1000; |
277
|
|
|
|
|
|
|
|
278
|
0
|
0
|
|
|
|
0
|
if ($k == 0) { |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
279
|
0
|
|
|
|
|
0
|
$jde0 = 1721139.29189 + |
280
|
|
|
|
|
|
|
(365242.13740 * $y) + |
281
|
|
|
|
|
|
|
(0.06134 * _pow($y, 2)) + |
282
|
|
|
|
|
|
|
(0.00111 * _pow($y, 3)) - |
283
|
|
|
|
|
|
|
(0.00071 * _pow($y, 4)); |
284
|
|
|
|
|
|
|
} |
285
|
|
|
|
|
|
|
elsif ($k == 1) { |
286
|
0
|
|
|
|
|
0
|
$jde0 = 1721233.25401 + |
287
|
|
|
|
|
|
|
(365241.72562 * $y) - |
288
|
|
|
|
|
|
|
(0.05323 * _pow($y, 2)) + |
289
|
|
|
|
|
|
|
(0.00907 * _pow($y, 3)) + |
290
|
|
|
|
|
|
|
(0.00025 * _pow($y, 4)); |
291
|
|
|
|
|
|
|
} |
292
|
|
|
|
|
|
|
elsif ($k == 2) { |
293
|
0
|
|
|
|
|
0
|
$jde0 = 1721325.70455 + |
294
|
|
|
|
|
|
|
(365242.49558 * $y) - |
295
|
|
|
|
|
|
|
(0.11677 * _pow($y, 2)) - |
296
|
|
|
|
|
|
|
(0.00297 * _pow($y, 3)) + |
297
|
|
|
|
|
|
|
(0.00074 * _pow($y, 4)); |
298
|
|
|
|
|
|
|
} |
299
|
|
|
|
|
|
|
elsif ($k == 3) { |
300
|
0
|
|
|
|
|
0
|
$jde0 = 1721414.39987 + |
301
|
|
|
|
|
|
|
(365242.88257 * $y) - |
302
|
|
|
|
|
|
|
(0.00769 * _pow($y, 2)) - |
303
|
|
|
|
|
|
|
(0.00933 * _pow($y, 3)) - |
304
|
|
|
|
|
|
|
(0.00006 * _pow($y, 4)); |
305
|
|
|
|
|
|
|
} |
306
|
|
|
|
|
|
|
} |
307
|
|
|
|
|
|
|
elsif ($year > 1000 && $year <= 3000) { |
308
|
|
|
|
|
|
|
# Astronmical Algorithms, Chapter 27, page 178 (Table 27.B). |
309
|
8
|
|
|
|
|
22
|
$y = ($year - 2000) / 1000; |
310
|
|
|
|
|
|
|
|
311
|
8
|
100
|
|
|
|
35
|
if ($k == 0) { |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
312
|
2
|
|
|
|
|
8
|
$jde0 = 2451623.80984 + |
313
|
|
|
|
|
|
|
(365242.37404 * $y) + |
314
|
|
|
|
|
|
|
(0.05169 * _pow($y, 2)) - |
315
|
|
|
|
|
|
|
(0.00411 * _pow($y, 3)) - |
316
|
|
|
|
|
|
|
(0.00057 * _pow($y, 4)); |
317
|
|
|
|
|
|
|
} |
318
|
|
|
|
|
|
|
elsif ($k == 1) { |
319
|
2
|
|
|
|
|
9
|
$jde0 = 2451716.56767 + |
320
|
|
|
|
|
|
|
(365241.62603 * $y) + |
321
|
|
|
|
|
|
|
(0.00325 * _pow($y, 2)) + |
322
|
|
|
|
|
|
|
(0.00888 * _pow($y, 3)) - |
323
|
|
|
|
|
|
|
(0.00030 * _pow($y, 4)); |
324
|
|
|
|
|
|
|
} |
325
|
|
|
|
|
|
|
elsif ($k == 2) { |
326
|
2
|
|
|
|
|
6
|
$jde0 = 2451810.21715 + |
327
|
|
|
|
|
|
|
(365242.01767 * $y) - |
328
|
|
|
|
|
|
|
(0.11575 * _pow($y, 2)) + |
329
|
|
|
|
|
|
|
(0.00337 * _pow($y, 3)) + |
330
|
|
|
|
|
|
|
(0.00078 * _pow($y, 4)); |
331
|
|
|
|
|
|
|
} |
332
|
|
|
|
|
|
|
elsif ($k == 3) { |
333
|
2
|
|
|
|
|
6
|
$jde0 = 2451900.05952 + |
334
|
|
|
|
|
|
|
(365242.74049 * $y) - |
335
|
|
|
|
|
|
|
(0.06223 * _pow($y, 2)) - |
336
|
|
|
|
|
|
|
(0.00823 * _pow($y, 3)) + |
337
|
|
|
|
|
|
|
(0.00032 * _pow($y, 4)); |
338
|
|
|
|
|
|
|
} |
339
|
|
|
|
|
|
|
} |
340
|
|
|
|
|
|
|
|
341
|
8
|
|
|
|
|
13
|
return $jde0; |
342
|
|
|
|
|
|
|
} |
343
|
|
|
|
|
|
|
|
344
|
|
|
|
|
|
|
sub _pow { |
345
|
24
|
|
|
24
|
|
37
|
my ($n, $m) = @_; |
346
|
|
|
|
|
|
|
|
347
|
24
|
|
|
|
|
29
|
my $r = 1; |
348
|
24
|
|
|
|
|
37
|
foreach (1..$m) { |
349
|
72
|
|
|
|
|
81
|
$r *= $n; |
350
|
|
|
|
|
|
|
} |
351
|
|
|
|
|
|
|
|
352
|
24
|
|
|
|
|
54
|
return $r; |
353
|
|
|
|
|
|
|
} |
354
|
|
|
|
|
|
|
|
355
|
|
|
|
|
|
|
sub _cos { |
356
|
208
|
|
|
208
|
|
243
|
my ($degree) = @_; |
357
|
|
|
|
|
|
|
|
358
|
208
|
|
|
|
|
408
|
return cos(($degree * $PI)/180); |
359
|
|
|
|
|
|
|
} |
360
|
|
|
|
|
|
|
|
361
|
|
|
|
|
|
|
=head1 AUTHOR |
362
|
|
|
|
|
|
|
|
363
|
|
|
|
|
|
|
Mohammad S Anwar, C<< <mohammad.anwar at yahoo.com> >> |
364
|
|
|
|
|
|
|
|
365
|
|
|
|
|
|
|
=head1 REPOSITORY |
366
|
|
|
|
|
|
|
|
367
|
|
|
|
|
|
|
L<https://github.com/manwar/Astro-Utils> |
368
|
|
|
|
|
|
|
|
369
|
|
|
|
|
|
|
=head1 BUGS |
370
|
|
|
|
|
|
|
|
371
|
|
|
|
|
|
|
Please report any bugs or feature requests to C<bug-astro-utils at rt.cpan.org>, |
372
|
|
|
|
|
|
|
or through the web interface at L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Astro-Utils>. |
373
|
|
|
|
|
|
|
I will be notified and then you'll automatically be notified of progress on your |
374
|
|
|
|
|
|
|
bug as I make changes. |
375
|
|
|
|
|
|
|
|
376
|
|
|
|
|
|
|
=head1 SUPPORT |
377
|
|
|
|
|
|
|
|
378
|
|
|
|
|
|
|
You can find documentation for this module with the perldoc command. |
379
|
|
|
|
|
|
|
|
380
|
|
|
|
|
|
|
perldoc Astro::Utils |
381
|
|
|
|
|
|
|
|
382
|
|
|
|
|
|
|
You can also look for information at: |
383
|
|
|
|
|
|
|
|
384
|
|
|
|
|
|
|
=over 4 |
385
|
|
|
|
|
|
|
|
386
|
|
|
|
|
|
|
=item * RT: CPAN's request tracker (report bugs here) |
387
|
|
|
|
|
|
|
|
388
|
|
|
|
|
|
|
L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Astro-Utils> |
389
|
|
|
|
|
|
|
|
390
|
|
|
|
|
|
|
=item * AnnoCPAN: Annotated CPAN documentation |
391
|
|
|
|
|
|
|
|
392
|
|
|
|
|
|
|
L<http://annocpan.org/dist/Astro-Utils> |
393
|
|
|
|
|
|
|
|
394
|
|
|
|
|
|
|
=item * CPAN Ratings |
395
|
|
|
|
|
|
|
|
396
|
|
|
|
|
|
|
L<http://cpanratings.perl.org/d/Astro-Utils> |
397
|
|
|
|
|
|
|
|
398
|
|
|
|
|
|
|
=item * Search CPAN |
399
|
|
|
|
|
|
|
|
400
|
|
|
|
|
|
|
L<http://search.cpan.org/dist/Astro-Utils/> |
401
|
|
|
|
|
|
|
|
402
|
|
|
|
|
|
|
=back |
403
|
|
|
|
|
|
|
|
404
|
|
|
|
|
|
|
=head1 LICENSE AND COPYRIGHT |
405
|
|
|
|
|
|
|
|
406
|
|
|
|
|
|
|
Copyright (C) 2015 - 2017 Mohammad S Anwar. |
407
|
|
|
|
|
|
|
|
408
|
|
|
|
|
|
|
This program is free software; you can redistribute it and / or modify it under |
409
|
|
|
|
|
|
|
the terms of the the Artistic License (2.0). You may obtain a copy of the full |
410
|
|
|
|
|
|
|
license at: |
411
|
|
|
|
|
|
|
|
412
|
|
|
|
|
|
|
L<http://www.perlfoundation.org/artistic_license_2_0> |
413
|
|
|
|
|
|
|
|
414
|
|
|
|
|
|
|
Any use, modification, and distribution of the Standard or Modified Versions is |
415
|
|
|
|
|
|
|
governed by this Artistic License.By using, modifying or distributing the Package, |
416
|
|
|
|
|
|
|
you accept this license. Do not use, modify, or distribute the Package, if you do |
417
|
|
|
|
|
|
|
not accept this license. |
418
|
|
|
|
|
|
|
|
419
|
|
|
|
|
|
|
If your Modified Version has been derived from a Modified Version made by someone |
420
|
|
|
|
|
|
|
other than you,you are nevertheless required to ensure that your Modified Version |
421
|
|
|
|
|
|
|
complies with the requirements of this license. |
422
|
|
|
|
|
|
|
|
423
|
|
|
|
|
|
|
This license does not grant you the right to use any trademark, service mark, |
424
|
|
|
|
|
|
|
tradename, or logo of the Copyright Holder. |
425
|
|
|
|
|
|
|
|
426
|
|
|
|
|
|
|
This license includes the non-exclusive, worldwide, free-of-charge patent license |
427
|
|
|
|
|
|
|
to make, have made, use, offer to sell, sell, import and otherwise transfer the |
428
|
|
|
|
|
|
|
Package with respect to any patent claims licensable by the Copyright Holder that |
429
|
|
|
|
|
|
|
are necessarily infringed by the Package. If you institute patent litigation |
430
|
|
|
|
|
|
|
(including a cross-claim or counterclaim) against any party alleging that the |
431
|
|
|
|
|
|
|
Package constitutes direct or contributory patent infringement,then this Artistic |
432
|
|
|
|
|
|
|
License to you shall terminate on the date that such litigation is filed. |
433
|
|
|
|
|
|
|
|
434
|
|
|
|
|
|
|
Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER AND |
435
|
|
|
|
|
|
|
CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. THE IMPLIED |
436
|
|
|
|
|
|
|
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR |
437
|
|
|
|
|
|
|
NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY YOUR LOCAL LAW. UNLESS |
438
|
|
|
|
|
|
|
REQUIRED BY LAW, NO COPYRIGHT HOLDER OR CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, |
439
|
|
|
|
|
|
|
INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE |
440
|
|
|
|
|
|
|
OF THE PACKAGE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
441
|
|
|
|
|
|
|
|
442
|
|
|
|
|
|
|
=cut |
443
|
|
|
|
|
|
|
|
444
|
|
|
|
|
|
|
1; # End of Astro::Utils |