line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
=head1 NAME |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
Date::MSD - conversion between flavours of Mars Sol Date |
4
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
=head1 SYNOPSIS |
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
use Date::MSD qw(js_to_msd msd_to_cmsdnf cmsdn_to_js); |
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
$msd = js_to_msd($js); |
10
|
|
|
|
|
|
|
($cmsdn, $cmsdf) = msd_to_cmsdnf($msd, $tz); |
11
|
|
|
|
|
|
|
$js = cmsdn_to_js($cmsdn, $cmsdf, $tz); |
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
# and 69 other conversion functions |
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
=head1 DESCRIPTION |
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
For date and time calculations it is convenient to represent dates by |
18
|
|
|
|
|
|
|
a simple linear count of days, rather than in a particular calendar. |
19
|
|
|
|
|
|
|
This module performs conversions between different flavours of linear |
20
|
|
|
|
|
|
|
count of Martian solar days ("sols"). |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
Among Martian day count systems there are also some non-trivial |
23
|
|
|
|
|
|
|
differences of concept. There are systems that count only complete days, |
24
|
|
|
|
|
|
|
and those that count fractional days also. There are some that are fixed |
25
|
|
|
|
|
|
|
to Airy Mean Time (time on the Martian prime meridian), and others that |
26
|
|
|
|
|
|
|
are interpreted according to a timezone. The functions of this module |
27
|
|
|
|
|
|
|
appropriately handle the semantics of all the non-trivial conversions. |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
The day count systems supported by this module are Mars Sol Date, |
30
|
|
|
|
|
|
|
Julian Sol, and Chronological Mars Solar Date, each in both integral |
31
|
|
|
|
|
|
|
and fractional forms. |
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
=head2 Flavours of day count |
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
In the interests of orthogonality, all flavours of day count come in |
36
|
|
|
|
|
|
|
both integral and fractional varieties. Generally, there is a quantity |
37
|
|
|
|
|
|
|
named "XYZ" which is a real count of days since a particular epoch (an |
38
|
|
|
|
|
|
|
integer plus a fraction) and a corresponding quantity named "XYZN" ("XYZ |
39
|
|
|
|
|
|
|
Number") which is a count of complete days since the same epoch. XYZN is |
40
|
|
|
|
|
|
|
the integral part of XYZ. There is also a quantity named "XYZF" ("XYZ |
41
|
|
|
|
|
|
|
Fraction") which is a count of fractional days since the XYZN changed |
42
|
|
|
|
|
|
|
(at midnight). XYZF is the fractional part of XYZ, in the range [0, 1). |
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
This quantity naming pattern is derived from the naming of Terran day |
45
|
|
|
|
|
|
|
counts, particularly JD (Julian Date) and JDN (Julian Day Number) which |
46
|
|
|
|
|
|
|
have the described correspondence. The "XYZF" name type is a neologism, |
47
|
|
|
|
|
|
|
invented for L. |
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
All calendar dates given are in the Darian calendar for Mars. An hour |
50
|
|
|
|
|
|
|
number is appended to each date, separated by a "T"; hour 00 is midnight |
51
|
|
|
|
|
|
|
at the start of the day. An appended "Z" indicates that the date is to |
52
|
|
|
|
|
|
|
be interpreted in the timezone of the prime meridian (Airy Mean Time), |
53
|
|
|
|
|
|
|
and so is absolute; where any other timezone is to be used then this is |
54
|
|
|
|
|
|
|
explicitly noted. |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
=over |
57
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
=item MSD (Mars Sol Date) |
59
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
days elapsed since 0140-19-26T00Z (approximately MJD 5521.50 |
61
|
|
|
|
|
|
|
in Terrestrial Time). This epoch is the most recent near |
62
|
|
|
|
|
|
|
coincidence of midnight on the Martian prime meridian with noon |
63
|
|
|
|
|
|
|
on the Terran prime meridian. MSD is defined by the paper at |
64
|
|
|
|
|
|
|
L. |
65
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
=item JS (Julian Sol) |
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
days elapsed since 0000-01-01T00Z (MSD -94129.0) (approximately |
69
|
|
|
|
|
|
|
MJD -91195.22 in Terrestrial Time). This epoch is an Airy |
70
|
|
|
|
|
|
|
midnight approximating the last northward equinox prior to |
71
|
|
|
|
|
|
|
the first telescopic observations of Mars. The same epoch is |
72
|
|
|
|
|
|
|
used for the Darian calendar for Mars. JS is defined (but not |
73
|
|
|
|
|
|
|
explicitly) by the document describing the Darian calendar, at |
74
|
|
|
|
|
|
|
L. |
75
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
=item CMSD (Chronological Mars Solar Date) |
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
days elapsed since -0608-23-20T00 in the timezone of interest. |
79
|
|
|
|
|
|
|
CMSD = MSD + 500000.0 + Zoff, where Zoff is the timezone |
80
|
|
|
|
|
|
|
offset in fractional days. CMSD is defined by the memo at |
81
|
|
|
|
|
|
|
L. |
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
=back |
84
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
=head2 Meaning of the day |
86
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
A day count has meaning only in the context of a particular definition |
88
|
|
|
|
|
|
|
of "day". Potentially several time scales could be expressed in terms |
89
|
|
|
|
|
|
|
of a day count, just as Terran day counts such as MJD are used in the |
90
|
|
|
|
|
|
|
timescales UT1, UT2, UTC, TAI, TT, TCG, and others. For a day number |
91
|
|
|
|
|
|
|
to be meaningful it is necessary to be aware of which kind of day it |
92
|
|
|
|
|
|
|
is counting. Conversion between the different time scales is out of |
93
|
|
|
|
|
|
|
scope for this module. |
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
=cut |
96
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
package Date::MSD; |
98
|
|
|
|
|
|
|
|
99
|
1
|
|
|
1
|
|
34132
|
{ use 5.006; } |
|
1
|
|
|
|
|
5
|
|
|
1
|
|
|
|
|
48
|
|
100
|
1
|
|
|
1
|
|
6
|
use warnings; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
40
|
|
101
|
1
|
|
|
1
|
|
6
|
use strict; |
|
1
|
|
|
|
|
13
|
|
|
1
|
|
|
|
|
42
|
|
102
|
|
|
|
|
|
|
|
103
|
1
|
|
|
1
|
|
6
|
use Carp qw(croak); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
107
|
|
104
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
our $VERSION = "0.004"; |
106
|
|
|
|
|
|
|
|
107
|
1
|
|
|
1
|
|
1108
|
use parent "Exporter"; |
|
1
|
|
|
|
|
354
|
|
|
1
|
|
|
|
|
6
|
|
108
|
|
|
|
|
|
|
our @EXPORT_OK; |
109
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
my %msd_flavours = ( |
111
|
|
|
|
|
|
|
msd => { epoch_msd => 0 }, |
112
|
|
|
|
|
|
|
js => { epoch_msd => -94129.0 }, |
113
|
|
|
|
|
|
|
cmsd => { epoch_msd => -500000.0, zone => 1 }, |
114
|
|
|
|
|
|
|
); |
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
=head1 FUNCTIONS |
117
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
Day counts in this API may be native Perl numbers or C |
119
|
|
|
|
|
|
|
objects. Both are acceptable for all parameters, in any combination. |
120
|
|
|
|
|
|
|
In all conversion functions, the result is of the same type as the |
121
|
|
|
|
|
|
|
input, provided that the inputs are of consistent type. If native Perl |
122
|
|
|
|
|
|
|
numbers are supplied then the conversion is subject to floating point |
123
|
|
|
|
|
|
|
rounding, and possible overflow if the numbers are extremely large. |
124
|
|
|
|
|
|
|
The use of C is recommended to avoid these problems. |
125
|
|
|
|
|
|
|
With C the results are exact. |
126
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
There are conversion functions between all pairs of day count systems. |
128
|
|
|
|
|
|
|
This is a total of 72 conversion functions (including 12 identity |
129
|
|
|
|
|
|
|
functions). |
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
When converting between timezone-relative counts (CMSD) and absolute |
132
|
|
|
|
|
|
|
counts (MSD, JS), the timezone that is being used must be specified. |
133
|
|
|
|
|
|
|
It is given in a ZONE argument as a fractional number of days offset |
134
|
|
|
|
|
|
|
from the base time scale (typically Airy Mean Time). Beware of |
135
|
|
|
|
|
|
|
floating point rounding when the offset does not have a terminating |
136
|
|
|
|
|
|
|
binary representation; use of C avoids this problem. |
137
|
|
|
|
|
|
|
A ZONE parameter is not used when converting between absolute day counts |
138
|
|
|
|
|
|
|
(e.g., between MSD and JS) or between timezone-relative counts (e.g., |
139
|
|
|
|
|
|
|
between CMSD and CMSDN). |
140
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
=over |
142
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
=item msd_to_msd(MSD) |
144
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
=item msd_to_js(MSD) |
146
|
|
|
|
|
|
|
|
147
|
|
|
|
|
|
|
=item msd_to_cmsd(MSD, ZONE) |
148
|
|
|
|
|
|
|
|
149
|
|
|
|
|
|
|
=item js_to_msd(JS) |
150
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
=item js_to_js(JS) |
152
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
=item js_to_cmsd(JS, ZONE) |
154
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
=item cmsd_to_msd(CMSD, ZONE) |
156
|
|
|
|
|
|
|
|
157
|
|
|
|
|
|
|
=item cmsd_to_js(CMSD, ZONE) |
158
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
=item cmsd_to_cmsd(CMSD) |
160
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
These functions convert from one continuous day count to another. |
162
|
|
|
|
|
|
|
This principally involve a change of epoch. The input identifies a |
163
|
|
|
|
|
|
|
point in time, as a continuous day count of input flavour. The function |
164
|
|
|
|
|
|
|
returns the same point in time, represented as a continuous day count |
165
|
|
|
|
|
|
|
of output flavour. |
166
|
|
|
|
|
|
|
|
167
|
|
|
|
|
|
|
=item msd_to_msdnn(MSD) |
168
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
=item msd_to_jsnn(MSD) |
170
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
=item msd_to_cmsdnn(MSD, ZONE) |
172
|
|
|
|
|
|
|
|
173
|
|
|
|
|
|
|
=item js_to_msdnn(JS) |
174
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
=item js_to_jsnn(JS) |
176
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
=item js_to_cmsdnn(JS, ZONE) |
178
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
=item cmsd_to_msdnn(CMSD, ZONE) |
180
|
|
|
|
|
|
|
|
181
|
|
|
|
|
|
|
=item cmsd_to_jsnn(CMSD, ZONE) |
182
|
|
|
|
|
|
|
|
183
|
|
|
|
|
|
|
=item cmsd_to_cmsdnn(CMSD) |
184
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
These functions convert from a continuous day count to an integral day |
186
|
|
|
|
|
|
|
count. The input identifies a point in time, as a continuous day count |
187
|
|
|
|
|
|
|
of input flavour. The function returns the day number of output flavour |
188
|
|
|
|
|
|
|
that applies at that instant. The process throws away information about |
189
|
|
|
|
|
|
|
the time of (output-flavour) day. |
190
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
=item msd_to_msdnf(MSD) |
192
|
|
|
|
|
|
|
|
193
|
|
|
|
|
|
|
=item msd_to_jsnf(MSD) |
194
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
=item msd_to_cmsdnf(MSD, ZONE) |
196
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
=item js_to_msdnf(JS) |
198
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
=item js_to_jsnf(JS) |
200
|
|
|
|
|
|
|
|
201
|
|
|
|
|
|
|
=item js_to_cmsdnf(JS, ZONE) |
202
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
=item cmsd_to_msdnf(CMSD, ZONE) |
204
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
=item cmsd_to_jsnf(CMSD, ZONE) |
206
|
|
|
|
|
|
|
|
207
|
|
|
|
|
|
|
=item cmsd_to_cmsdnf(CMSD) |
208
|
|
|
|
|
|
|
|
209
|
|
|
|
|
|
|
These functions convert from a continuous day count to an integral day |
210
|
|
|
|
|
|
|
count with separate fraction. The input identifies a point in time, |
211
|
|
|
|
|
|
|
as a continuous day count of input flavour. The function returns a |
212
|
|
|
|
|
|
|
list of two items: the day number and fractional day of output flavour, |
213
|
|
|
|
|
|
|
which together identify the same point in time as the input. |
214
|
|
|
|
|
|
|
|
215
|
|
|
|
|
|
|
=item msd_to_msdn(MSD) |
216
|
|
|
|
|
|
|
|
217
|
|
|
|
|
|
|
=item msd_to_jsn(MSD) |
218
|
|
|
|
|
|
|
|
219
|
|
|
|
|
|
|
=item msd_to_cmsdn(MSD, ZONE) |
220
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
=item js_to_msdn(JS) |
222
|
|
|
|
|
|
|
|
223
|
|
|
|
|
|
|
=item js_to_jsn(JS) |
224
|
|
|
|
|
|
|
|
225
|
|
|
|
|
|
|
=item js_to_cmsdn(JS, ZONE) |
226
|
|
|
|
|
|
|
|
227
|
|
|
|
|
|
|
=item cmsd_to_msdn(CMSD, ZONE) |
228
|
|
|
|
|
|
|
|
229
|
|
|
|
|
|
|
=item cmsd_to_jsn(CMSD, ZONE) |
230
|
|
|
|
|
|
|
|
231
|
|
|
|
|
|
|
=item cmsd_to_cmsdn(CMSD) |
232
|
|
|
|
|
|
|
|
233
|
|
|
|
|
|
|
These functions convert from a continuous day count to an integral day |
234
|
|
|
|
|
|
|
count, possibly with separate fraction. The input identifies a point in |
235
|
|
|
|
|
|
|
time, as a continuous day count of input flavour. If called in scalar |
236
|
|
|
|
|
|
|
context, the function returns the day number of output flavour that |
237
|
|
|
|
|
|
|
applies at that instant, throwing away information about the time of |
238
|
|
|
|
|
|
|
(output-flavour) day. If called in list context, the function returns a |
239
|
|
|
|
|
|
|
list of two items: the day number and fractional day of output flavour, |
240
|
|
|
|
|
|
|
which together identify the same point in time as the input. |
241
|
|
|
|
|
|
|
|
242
|
|
|
|
|
|
|
These functions are not recommended, because the context-sensitive |
243
|
|
|
|
|
|
|
return convention makes their use error-prone. They are retained for |
244
|
|
|
|
|
|
|
backward compatibility. You should prefer to use the more specific |
245
|
|
|
|
|
|
|
functions shown above. |
246
|
|
|
|
|
|
|
|
247
|
|
|
|
|
|
|
=item msdn_to_msd(MSDN, MSDF) |
248
|
|
|
|
|
|
|
|
249
|
|
|
|
|
|
|
=item msdn_to_js(MSDN, MSDF) |
250
|
|
|
|
|
|
|
|
251
|
|
|
|
|
|
|
=item msdn_to_cmsd(MSDN, MSDF, ZONE) |
252
|
|
|
|
|
|
|
|
253
|
|
|
|
|
|
|
=item jsn_to_msd(JSN, JSF) |
254
|
|
|
|
|
|
|
|
255
|
|
|
|
|
|
|
=item jsn_to_js(JSN, JSF) |
256
|
|
|
|
|
|
|
|
257
|
|
|
|
|
|
|
=item jsn_to_cmsd(JSN, JSF, ZONE) |
258
|
|
|
|
|
|
|
|
259
|
|
|
|
|
|
|
=item cmsdn_to_msd(CMSDN, CMSDF, ZONE) |
260
|
|
|
|
|
|
|
|
261
|
|
|
|
|
|
|
=item cmsdn_to_js(CMSDN, CMSDF, ZONE) |
262
|
|
|
|
|
|
|
|
263
|
|
|
|
|
|
|
=item cmsdn_to_cmsd(CMSDN, CMSDF) |
264
|
|
|
|
|
|
|
|
265
|
|
|
|
|
|
|
These functions convert from an integral day count with separate fraction |
266
|
|
|
|
|
|
|
to a continuous day count. The input identifies a point in time, as |
267
|
|
|
|
|
|
|
an integral day number of input flavour plus day fraction in the range |
268
|
|
|
|
|
|
|
[0, 1). The function returns the same point in time, represented as a |
269
|
|
|
|
|
|
|
continuous day count of output flavour. |
270
|
|
|
|
|
|
|
|
271
|
|
|
|
|
|
|
=item msdn_to_msdnn(MSDN[, MSDF]) |
272
|
|
|
|
|
|
|
|
273
|
|
|
|
|
|
|
=item msdn_to_jsnn(MSDN[, MSDF]) |
274
|
|
|
|
|
|
|
|
275
|
|
|
|
|
|
|
=item msdn_to_cmsdnn(MSDN, MSDF, ZONE) |
276
|
|
|
|
|
|
|
|
277
|
|
|
|
|
|
|
=item jsn_to_msdnn(JSN[, JSF]) |
278
|
|
|
|
|
|
|
|
279
|
|
|
|
|
|
|
=item jsn_to_jsnn(JSN[, JSF]) |
280
|
|
|
|
|
|
|
|
281
|
|
|
|
|
|
|
=item jsn_to_cmsdnn(JSN, JSF, ZONE) |
282
|
|
|
|
|
|
|
|
283
|
|
|
|
|
|
|
=item cmsdn_to_msdnn(CMSDN, CMSDF, ZONE) |
284
|
|
|
|
|
|
|
|
285
|
|
|
|
|
|
|
=item cmsdn_to_jsnn(CMSDN, CMSDF, ZONE) |
286
|
|
|
|
|
|
|
|
287
|
|
|
|
|
|
|
=item cmsdn_to_cmsdnn(CMSDN[, CMSDF]) |
288
|
|
|
|
|
|
|
|
289
|
|
|
|
|
|
|
These functions convert from an integral day count with separate fraction |
290
|
|
|
|
|
|
|
to an integral day count. The input identifies a point in time, as an |
291
|
|
|
|
|
|
|
integral day number of input flavour plus day fraction in the range |
292
|
|
|
|
|
|
|
[0, 1). The function returns the day number of output flavour that |
293
|
|
|
|
|
|
|
applies at that instant. The process throws away information about |
294
|
|
|
|
|
|
|
the time of (output-flavour) day. If converting between systems that |
295
|
|
|
|
|
|
|
delimit days identically (e.g., between JS and MSD), the day fraction |
296
|
|
|
|
|
|
|
makes no difference and may be omitted from the input. |
297
|
|
|
|
|
|
|
|
298
|
|
|
|
|
|
|
=item msdn_to_msdnf(MSDN, MSDF) |
299
|
|
|
|
|
|
|
|
300
|
|
|
|
|
|
|
=item msdn_to_jsnf(MSDN, MSDF) |
301
|
|
|
|
|
|
|
|
302
|
|
|
|
|
|
|
=item msdn_to_cmsdnf(MSDN, MSDF, ZONE) |
303
|
|
|
|
|
|
|
|
304
|
|
|
|
|
|
|
=item jsn_to_msdnf(JSN, JSF) |
305
|
|
|
|
|
|
|
|
306
|
|
|
|
|
|
|
=item jsn_to_jsnf(JSN, JSF) |
307
|
|
|
|
|
|
|
|
308
|
|
|
|
|
|
|
=item jsn_to_cmsdnf(JSN, JSF, ZONE) |
309
|
|
|
|
|
|
|
|
310
|
|
|
|
|
|
|
=item cmsdn_to_msdnf(CMSDN, CMSDF, ZONE) |
311
|
|
|
|
|
|
|
|
312
|
|
|
|
|
|
|
=item cmsdn_to_jsnf(CMSDN, CMSDF, ZONE) |
313
|
|
|
|
|
|
|
|
314
|
|
|
|
|
|
|
=item cmsdn_to_cmsdnf(CMSDN, CMSDF) |
315
|
|
|
|
|
|
|
|
316
|
|
|
|
|
|
|
These functions convert from one integral day count with separate |
317
|
|
|
|
|
|
|
fraction to another. The input identifies a point in time, as an |
318
|
|
|
|
|
|
|
integral day number of input flavour plus day fraction in the range |
319
|
|
|
|
|
|
|
[0, 1). The function returns a list of two items: the day number and |
320
|
|
|
|
|
|
|
fractional day of output flavour, which together identify the same point |
321
|
|
|
|
|
|
|
in time as the input. |
322
|
|
|
|
|
|
|
|
323
|
|
|
|
|
|
|
=item msdn_to_msdn(MSDN[, MSDF]) |
324
|
|
|
|
|
|
|
|
325
|
|
|
|
|
|
|
=item msdn_to_jsn(MSDN[, MSDF]) |
326
|
|
|
|
|
|
|
|
327
|
|
|
|
|
|
|
=item msdn_to_cmsdn(MSDN, MSDF, ZONE) |
328
|
|
|
|
|
|
|
|
329
|
|
|
|
|
|
|
=item jsn_to_msdn(JSN[, JSF]) |
330
|
|
|
|
|
|
|
|
331
|
|
|
|
|
|
|
=item jsn_to_jsn(JSN[, JSF]) |
332
|
|
|
|
|
|
|
|
333
|
|
|
|
|
|
|
=item jsn_to_cmsdn(JSN, JSF, ZONE) |
334
|
|
|
|
|
|
|
|
335
|
|
|
|
|
|
|
=item cmsdn_to_msdn(CMSDN, CMSDF, ZONE) |
336
|
|
|
|
|
|
|
|
337
|
|
|
|
|
|
|
=item cmsdn_to_jsn(CMSDN, CMSDF, ZONE) |
338
|
|
|
|
|
|
|
|
339
|
|
|
|
|
|
|
=item cmsdn_to_cmsdn(CMSDN[, CMSDF]) |
340
|
|
|
|
|
|
|
|
341
|
|
|
|
|
|
|
These functions convert from an integral day count with separate fraction |
342
|
|
|
|
|
|
|
to an integral day count, possibly with separate fraction. The input |
343
|
|
|
|
|
|
|
identifies a point in time, as an integral day number of input flavour |
344
|
|
|
|
|
|
|
plus day fraction in the range [0, 1). If called in scalar context, the |
345
|
|
|
|
|
|
|
function returns the day number of output flavour that applies at that |
346
|
|
|
|
|
|
|
instant, throwing away information about the time of (output-flavour) day. |
347
|
|
|
|
|
|
|
If called in list context, the function returns a list of two items: |
348
|
|
|
|
|
|
|
the day number and fractional day of output flavour, which together |
349
|
|
|
|
|
|
|
identify the same point in time as the input. |
350
|
|
|
|
|
|
|
|
351
|
|
|
|
|
|
|
If converting between systems that delimit days identically (e.g., |
352
|
|
|
|
|
|
|
between JS and MSD), the day fraction makes no difference to the integral |
353
|
|
|
|
|
|
|
day number of the output, and may be omitted from the input. If the day |
354
|
|
|
|
|
|
|
fraction is extracted from the output when it wasn't supplied as input, |
355
|
|
|
|
|
|
|
it will default to zero. |
356
|
|
|
|
|
|
|
|
357
|
|
|
|
|
|
|
These functions are not recommended, because the context-sensitive |
358
|
|
|
|
|
|
|
return convention makes their use error-prone. They are retained for |
359
|
|
|
|
|
|
|
backward compatibility. You should prefer to use the more specific |
360
|
|
|
|
|
|
|
functions shown above. |
361
|
|
|
|
|
|
|
|
362
|
|
|
|
|
|
|
=cut |
363
|
|
|
|
|
|
|
|
364
|
|
|
|
|
|
|
eval { local $SIG{__DIE__}; |
365
|
|
|
|
|
|
|
require POSIX; |
366
|
|
|
|
|
|
|
*_floor = \&POSIX::floor; |
367
|
|
|
|
|
|
|
}; |
368
|
|
|
|
|
|
|
if($@ ne "") { |
369
|
|
|
|
|
|
|
*_floor = sub($) { |
370
|
|
|
|
|
|
|
my $i = int($_[0]); |
371
|
|
|
|
|
|
|
return $i == $_[0] || $_[0] > 0 ? $i : $i - 1; |
372
|
|
|
|
|
|
|
} |
373
|
|
|
|
|
|
|
} |
374
|
|
|
|
|
|
|
|
375
|
|
|
|
|
|
|
sub _check_dn($$) { |
376
|
504
|
100
|
|
504
|
|
2472
|
croak "purported day number $_[0] is not an integer" |
|
|
50
|
|
|
|
|
|
377
|
|
|
|
|
|
|
unless ref($_[0]) ? $_[0]->is_int : $_[0] == int($_[0]); |
378
|
504
|
50
|
33
|
|
|
12063
|
croak "purported day fraction $_[1] is out of range [0, 1)" |
379
|
|
|
|
|
|
|
unless $_[1] >= 0 && $_[1] < 1; |
380
|
|
|
|
|
|
|
} |
381
|
|
|
|
|
|
|
|
382
|
|
|
|
|
|
|
sub _ret_dnn($) { |
383
|
720
|
100
|
|
720
|
|
116830
|
my $dn = ref($_[0]) eq "Math::BigRat" ? |
384
|
|
|
|
|
|
|
$_[0]->copy->bfloor : _floor($_[0]); |
385
|
720
|
|
|
|
|
20425
|
return $dn; |
386
|
|
|
|
|
|
|
} |
387
|
|
|
|
|
|
|
|
388
|
|
|
|
|
|
|
sub _ret_dnf($) { |
389
|
288
|
|
|
288
|
|
60374
|
my $dn = &_ret_dnn; |
390
|
288
|
|
|
|
|
1183
|
return ($dn, $_[0] - $dn); |
391
|
|
|
|
|
|
|
} |
392
|
|
|
|
|
|
|
|
393
|
|
|
|
|
|
|
sub _ret_dn($) { |
394
|
288
|
100
|
|
288
|
|
110138
|
return wantarray ? &_ret_dnf : &_ret_dnn; |
395
|
|
|
|
|
|
|
} |
396
|
|
|
|
|
|
|
|
397
|
|
|
|
|
|
|
foreach my $src (keys %msd_flavours) { foreach my $dst (keys %msd_flavours) { |
398
|
|
|
|
|
|
|
my $ediff = $msd_flavours{$src}->{epoch_msd} - |
399
|
|
|
|
|
|
|
$msd_flavours{$dst}->{epoch_msd}; |
400
|
|
|
|
|
|
|
my $ediffh = $ediff == int($ediff) ? 0 : 0.5; |
401
|
|
|
|
|
|
|
my $src_zone = !!$msd_flavours{$src}->{zone}; |
402
|
|
|
|
|
|
|
my $dst_zone = !!$msd_flavours{$dst}->{zone}; |
403
|
|
|
|
|
|
|
my($zp, $z1, $z2); |
404
|
|
|
|
|
|
|
if($src_zone == $dst_zone) { |
405
|
|
|
|
|
|
|
$zp = $z1 = $z2 = ""; |
406
|
|
|
|
|
|
|
} else { |
407
|
|
|
|
|
|
|
$zp = "\$"; |
408
|
|
|
|
|
|
|
my $zsign = $src_zone ? "-" : "+"; |
409
|
|
|
|
|
|
|
$z1 = "$zsign \$_[1]"; |
410
|
|
|
|
|
|
|
$z2 = "$zsign \$_[2]"; |
411
|
|
|
|
|
|
|
} |
412
|
16
|
|
|
16
|
1
|
25273
|
eval "sub ${src}_to_${dst}(\$${zp}) { \$_[0] + (${ediff}) ${z1} }"; |
|
16
|
|
|
16
|
1
|
23796
|
|
|
16
|
|
|
16
|
1
|
25820
|
|
|
16
|
|
|
16
|
1
|
26413
|
|
|
16
|
|
|
16
|
1
|
19271
|
|
|
16
|
|
|
16
|
1
|
20447
|
|
|
16
|
|
|
16
|
1
|
29333
|
|
|
16
|
|
|
16
|
1
|
23684
|
|
|
16
|
|
|
16
|
1
|
117996
|
|
413
|
|
|
|
|
|
|
push @EXPORT_OK, "${src}_to_${dst}"; |
414
|
16
|
|
|
16
|
1
|
11748
|
eval "sub ${src}_to_${dst}nn(\$${zp}) { |
|
16
|
|
|
16
|
1
|
11628
|
|
|
16
|
|
|
16
|
1
|
11886
|
|
|
16
|
|
|
16
|
1
|
11430
|
|
|
16
|
|
|
16
|
1
|
8279
|
|
|
16
|
|
|
16
|
1
|
9289
|
|
|
16
|
|
|
16
|
1
|
10190
|
|
|
16
|
|
|
16
|
1
|
8087
|
|
|
16
|
|
|
16
|
1
|
10602
|
|
415
|
|
|
|
|
|
|
_ret_dnn(\$_[0] + (${ediff}) ${z1}) |
416
|
|
|
|
|
|
|
}"; |
417
|
|
|
|
|
|
|
push @EXPORT_OK, "${src}_to_${dst}nn"; |
418
|
8
|
|
|
8
|
1
|
8622
|
eval "sub ${src}_to_${dst}nf(\$${zp}) { |
|
8
|
|
|
8
|
1
|
7209
|
|
|
8
|
|
|
8
|
1
|
8056
|
|
|
8
|
|
|
8
|
1
|
7747
|
|
|
8
|
|
|
8
|
1
|
6422
|
|
|
8
|
|
|
8
|
1
|
6853
|
|
|
8
|
|
|
8
|
1
|
18585
|
|
|
8
|
|
|
8
|
1
|
6565
|
|
|
8
|
|
|
8
|
1
|
10209
|
|
419
|
|
|
|
|
|
|
_ret_dnf(\$_[0] + (${ediff}) ${z1}) |
420
|
|
|
|
|
|
|
}"; |
421
|
|
|
|
|
|
|
push @EXPORT_OK, "${src}_to_${dst}nf"; |
422
|
16
|
|
|
16
|
1
|
26917
|
eval "sub ${src}_to_${dst}n(\$${zp}) { |
|
16
|
|
|
16
|
1
|
19773
|
|
|
16
|
|
|
16
|
1
|
23853
|
|
|
16
|
|
|
16
|
1
|
25199
|
|
|
16
|
|
|
16
|
1
|
19627
|
|
|
16
|
|
|
16
|
1
|
20603
|
|
|
16
|
|
|
16
|
1
|
16550
|
|
|
16
|
|
|
16
|
1
|
21112
|
|
|
16
|
|
|
16
|
1
|
20649
|
|
423
|
|
|
|
|
|
|
_ret_dn(\$_[0] + (${ediff}) ${z1}) |
424
|
|
|
|
|
|
|
}"; |
425
|
|
|
|
|
|
|
push @EXPORT_OK, "${src}_to_${dst}n"; |
426
|
16
|
|
|
16
|
1
|
22130
|
eval "sub ${src}n_to_${dst}(\$\$${zp}) { |
|
16
|
|
|
16
|
1
|
3453
|
|
|
16
|
|
|
16
|
1
|
28738
|
|
|
16
|
|
|
16
|
1
|
3084
|
|
|
16
|
|
|
16
|
1
|
24678
|
|
|
16
|
|
|
16
|
1
|
3863
|
|
|
16
|
|
|
16
|
1
|
23124
|
|
|
16
|
|
|
16
|
1
|
3245
|
|
|
16
|
|
|
16
|
1
|
36435
|
|
|
16
|
|
|
|
|
3169
|
|
|
16
|
|
|
|
|
17063
|
|
|
16
|
|
|
|
|
3050
|
|
|
16
|
|
|
|
|
18516
|
|
|
16
|
|
|
|
|
2787
|
|
|
16
|
|
|
|
|
21330
|
|
|
16
|
|
|
|
|
3077
|
|
|
16
|
|
|
|
|
18979
|
|
|
16
|
|
|
|
|
3085
|
|
427
|
|
|
|
|
|
|
_check_dn(\$_[0], \$_[1]); |
428
|
|
|
|
|
|
|
\$_[0] + \$_[1] + (${ediff}) ${z2} |
429
|
|
|
|
|
|
|
}"; |
430
|
|
|
|
|
|
|
push @EXPORT_OK, "${src}n_to_${dst}"; |
431
|
|
|
|
|
|
|
my($tp, $tc); |
432
|
|
|
|
|
|
|
if($ediffh == 0 && $src_zone == $dst_zone) { |
433
|
|
|
|
|
|
|
$tp = ";"; |
434
|
|
|
|
|
|
|
$tc = "push \@_, 0 if \@_ == 1;"; |
435
|
|
|
|
|
|
|
} else { |
436
|
|
|
|
|
|
|
$tp = $tc = ""; |
437
|
|
|
|
|
|
|
} |
438
|
16
|
50
|
|
16
|
1
|
15404
|
eval "sub ${src}n_to_${dst}nn(\$${tp}\$${zp}) { $tc |
|
16
|
50
|
|
16
|
1
|
63
|
|
|
16
|
50
|
|
16
|
1
|
3166
|
|
|
16
|
50
|
|
16
|
1
|
15754
|
|
|
16
|
50
|
|
16
|
1
|
2832
|
|
|
16
|
|
|
16
|
1
|
16748
|
|
|
16
|
|
|
16
|
1
|
3000
|
|
|
16
|
|
|
16
|
1
|
22639
|
|
|
16
|
|
|
16
|
1
|
2988
|
|
|
16
|
|
|
|
|
12493
|
|
|
16
|
|
|
|
|
59
|
|
|
16
|
|
|
|
|
2856
|
|
|
16
|
|
|
|
|
11201
|
|
|
16
|
|
|
|
|
49
|
|
|
16
|
|
|
|
|
2729
|
|
|
16
|
|
|
|
|
13541
|
|
|
16
|
|
|
|
|
2620
|
|
|
16
|
|
|
|
|
12217
|
|
|
16
|
|
|
|
|
58
|
|
|
16
|
|
|
|
|
9699
|
|
|
16
|
|
|
|
|
12989
|
|
|
16
|
|
|
|
|
68
|
|
|
16
|
|
|
|
|
3219
|
|
439
|
|
|
|
|
|
|
_check_dn(\$_[0], \$_[1]); |
440
|
|
|
|
|
|
|
_ret_dnn(\$_[0] + \$_[1] + ($ediff) ${z2}) |
441
|
|
|
|
|
|
|
}"; |
442
|
|
|
|
|
|
|
push @EXPORT_OK, "${src}n_to_${dst}nn"; |
443
|
8
|
|
|
8
|
1
|
8797
|
eval "sub ${src}n_to_${dst}nf(\$\$${zp}) { |
|
8
|
|
|
8
|
1
|
1537
|
|
|
8
|
|
|
8
|
1
|
7272
|
|
|
8
|
|
|
8
|
1
|
2034
|
|
|
8
|
|
|
8
|
1
|
7005
|
|
|
8
|
|
|
8
|
1
|
1479
|
|
|
8
|
|
|
8
|
1
|
14396
|
|
|
8
|
|
|
8
|
1
|
2490
|
|
|
8
|
|
|
8
|
1
|
7259
|
|
|
8
|
|
|
|
|
1570
|
|
|
8
|
|
|
|
|
6067
|
|
|
8
|
|
|
|
|
1337
|
|
|
8
|
|
|
|
|
5754
|
|
|
8
|
|
|
|
|
1458
|
|
|
8
|
|
|
|
|
7069
|
|
|
8
|
|
|
|
|
1453
|
|
|
8
|
|
|
|
|
7729
|
|
|
8
|
|
|
|
|
1688
|
|
444
|
|
|
|
|
|
|
_check_dn(\$_[0], \$_[1]); |
445
|
|
|
|
|
|
|
_ret_dnf(\$_[0] + \$_[1] + ($ediff) ${z2}) |
446
|
|
|
|
|
|
|
}"; |
447
|
|
|
|
|
|
|
push @EXPORT_OK, "${src}n_to_${dst}nf"; |
448
|
16
|
50
|
|
16
|
1
|
16840
|
eval "sub ${src}n_to_${dst}n(\$${tp}\$${zp}) { $tc |
|
16
|
50
|
|
16
|
1
|
63
|
|
|
16
|
50
|
|
16
|
1
|
3218
|
|
|
16
|
50
|
|
16
|
1
|
15646
|
|
|
16
|
50
|
|
16
|
1
|
2870
|
|
|
16
|
|
|
16
|
1
|
15257
|
|
|
16
|
|
|
16
|
1
|
3556
|
|
|
16
|
|
|
16
|
1
|
20449
|
|
|
16
|
|
|
16
|
1
|
4625
|
|
|
16
|
|
|
|
|
14073
|
|
|
16
|
|
|
|
|
66
|
|
|
16
|
|
|
|
|
3900
|
|
|
16
|
|
|
|
|
14422
|
|
|
16
|
|
|
|
|
58
|
|
|
16
|
|
|
|
|
2879
|
|
|
16
|
|
|
|
|
13736
|
|
|
16
|
|
|
|
|
3080
|
|
|
16
|
|
|
|
|
15278
|
|
|
16
|
|
|
|
|
59
|
|
|
16
|
|
|
|
|
4474
|
|
|
16
|
|
|
|
|
20864
|
|
|
16
|
|
|
|
|
67
|
|
|
16
|
|
|
|
|
2971
|
|
449
|
|
|
|
|
|
|
_check_dn(\$_[0], \$_[1]); |
450
|
|
|
|
|
|
|
_ret_dn(\$_[0] + \$_[1] + ($ediff) ${z2}) |
451
|
|
|
|
|
|
|
}"; |
452
|
|
|
|
|
|
|
push @EXPORT_OK, "${src}n_to_${dst}n"; |
453
|
|
|
|
|
|
|
} } |
454
|
|
|
|
|
|
|
|
455
|
|
|
|
|
|
|
=back |
456
|
|
|
|
|
|
|
|
457
|
|
|
|
|
|
|
=head1 SEE ALSO |
458
|
|
|
|
|
|
|
|
459
|
|
|
|
|
|
|
L, |
460
|
|
|
|
|
|
|
L |
461
|
|
|
|
|
|
|
|
462
|
|
|
|
|
|
|
=head1 AUTHOR |
463
|
|
|
|
|
|
|
|
464
|
|
|
|
|
|
|
Andrew Main (Zefram) |
465
|
|
|
|
|
|
|
|
466
|
|
|
|
|
|
|
=head1 COPYRIGHT |
467
|
|
|
|
|
|
|
|
468
|
|
|
|
|
|
|
Copyright (C) 2007, 2009, 2010, 2012 |
469
|
|
|
|
|
|
|
Andrew Main (Zefram) |
470
|
|
|
|
|
|
|
|
471
|
|
|
|
|
|
|
=head1 LICENSE |
472
|
|
|
|
|
|
|
|
473
|
|
|
|
|
|
|
This module is free software; you can redistribute it and/or modify it |
474
|
|
|
|
|
|
|
under the same terms as Perl itself. |
475
|
|
|
|
|
|
|
|
476
|
|
|
|
|
|
|
=cut |
477
|
|
|
|
|
|
|
|
478
|
|
|
|
|
|
|
1; |