File Coverage

blib/lib/Time/UTC/Now.pm
Criterion Covered Total %
statement 21 21 100.0
branch n/a
condition n/a
subroutine 8 8 100.0
pod 2 2 100.0
total 31 31 100.0


line stmt bran cond sub pod time code
1             =head1 NAME
2              
3             Time::UTC::Now - determine current time in UTC correctly
4              
5             =head1 SYNOPSIS
6              
7             use Time::UTC::Now qw(
8             now_utc_rat now_utc_sna now_utc_flt now_utc_dec);
9              
10             ($day, $secs, $bound) = now_utc_rat;
11             ($day, $secs, $bound) = now_utc_rat(1);
12             ($day, $secs, $bound) = now_utc_sna;
13             ($day, $secs, $bound) = now_utc_sna(1);
14             ($day, $secs, $bound) = now_utc_flt;
15             ($day, $secs, $bound) = now_utc_flt(1);
16             ($day, $secs, $bound) = now_utc_dec;
17             ($day, $secs, $bound) = now_utc_dec(1);
18              
19             use Time::UTC::Now qw(utc_day_to_mjdn utc_day_to_cjdn);
20              
21             $mjdn = utc_day_to_mjdn($day);
22             $cjdn = utc_day_to_cjdn($day);
23              
24             =head1 DESCRIPTION
25              
26             This module is one answer to the question "what time is it?".
27             It determines the current time on the UTC scale, handling leap seconds
28             correctly, and puts a bound on how inaccurate it could be. It is the
29             rigorously correct approach to determining civil time. It is designed to
30             interoperate with L, which knows all about the UTC time scale.
31              
32             UTC (Coordinated Universal Time) is a time scale derived from
33             International Atomic Time (TAI). UTC divides time up into days, and
34             each day into seconds. The seconds are atomically-realised SI seconds,
35             of uniform length. Most UTC days are exactly 86400 seconds long,
36             but occasionally there is a day of length 86401 s or (theoretically)
37             86399 s. These leap seconds are used to keep the UTC day approximately
38             synchronised with the non-uniform rotation of the Earth. (Prior to 1972
39             a different mechanism was used for UTC, but that's not an issue here.)
40              
41             Because UTC days have differing lengths, instants on the UTC scale
42             are identified here by the combination of a day number and a number
43             of seconds since midnight within the day. In this module the day
44             number is the integral number of days since 1958-01-01, which is the
45             epoch of the TAI scale which underlies UTC. This is the convention
46             used by the C module. That module has some functions to
47             format these numbers for display. For a more general solution, use
48             the C function to translate to a standard Modified
49             Julian Day Number or the C function to translate to a
50             standard Chronological Julian Day Number, which can be used as input to
51             a calendar module.
52              
53             =cut
54              
55             package Time::UTC::Now;
56              
57 3     3   248300 { use 5.006; }
  3         18  
58 3     3   23 use warnings;
  3         10  
  3         125  
59 3     3   21 use strict;
  3         15  
  3         173  
60              
61             our $VERSION = "0.011";
62              
63 3     3   1799 use parent "Exporter";
  3         1641  
  3         22  
64             our @EXPORT_OK = qw(
65             now_utc_rat now_utc_sna now_utc_flt now_utc_dec
66             utc_day_to_mjdn utc_day_to_cjdn
67             );
68              
69             require XSLoader;
70             XSLoader::load("Time::UTC::Now", $VERSION);
71              
72             =head1 FUNCTIONS
73              
74             =head2 Time determination
75              
76             Each of these functions determines the current UTC time and returns it.
77             They vary in the form in which the time is returned. In each case, the
78             function returns a list of three values. The first two values identify
79             a current UTC instant, in the form of a day number (number of days since
80             the TAI epoch) and a number of seconds since midnight within the day.
81             The third value is an inaccuracy bound, as a number of seconds, or
82             C if no accurate answer could be determined.
83              
84             If an inaccuracy bound is returned then the function is claiming to have
85             answered correctly, to within the specified margin. That is, some instant
86             during the execution of the function is within the specified margin of
87             the instant identified. (This semantic differs from older current-time
88             interfaces that are content to return an instant that has already passed.)
89             The inaccuracy bound describes the actual time represented in the return
90             values, not some internal value that was rounded to generate the return
91             values.
92              
93             The inaccuracy bound is measured in UTC seconds; that is, in SI seconds
94             on the Terran geoid as realised by atomic clocks. This differs from SI
95             seconds at the computer's location, but the difference is only apparent
96             if the computer hardware is significantly time dilated with respect to
97             the geoid.
98              
99             If C is returned instead of an inaccuracy bound then the function
100             could not find a trustable answer. Either the clock available was not
101             properly synchronised or its accuracy could not be established. Whatever
102             time could be found is returned, but the function makes no claim that it
103             is accurate. It should be treated with suspicion. In practice, clocks
104             of this nature are especially likely to misbehave around leap seconds.
105              
106             Each function will C if it can't find a plausible time at all.
107             If the I parameter is supplied and true then it will
108             also die if it could not find an accurate answer, instead of returning
109             with C for the inaccuracy bound.
110              
111             =over
112              
113             =item now_utc_rat([DEMAND_ACCURACY])
114              
115             All three return values are in the form of C objects.
116              
117             This retains full resolution, is future-proof, and is easy to manipulate,
118             but beware that C is currently rather slow. If performance
119             is a problem then consider using one of the functions below that return
120             the results in other formats.
121              
122             =item now_utc_sna([DEMAND_ACCURACY])
123              
124             The day number is returned as a Perl integer. The time since midnight
125             and the inaccuracy bound (if present) are each returned in the form of
126             a three-element array, giving a high-resolution fixed-point number of
127             seconds. The first element is the integral number of whole seconds, the
128             second is an integral number of nanoseconds in the range [0, 1000000000),
129             and the third is an integral number of attoseconds in the same range.
130              
131             This form of return value is fairly efficient. It is convenient for
132             decimal output, but awkward to do arithmetic with. Its resolution is
133             adequate for the foreseeable future, but could in principle be obsoleted
134             some day.
135              
136             It is presumed that native integer formats will grow fast enough to always
137             represent the day number fully; if not, 31 bits will overflow late in
138             the sixth megayear of the Common Era. (Average day length by then is
139             projected to be around 86520 s, posing more serious problems for UTC.)
140              
141             =item now_utc_flt([DEMAND_ACCURACY])
142              
143             All the results are returned as native Perl numbers. The day number is
144             returned as a Perl integer, with the same caveat as for C.
145             The other two items are floating point numbers.
146              
147             This form of return value is very efficient and easy to manipulate.
148             However, its resolution is limited, rendering it obsolete in the near
149             future unless floating point number formats get bigger.
150              
151             =item now_utc_dec([DEMAND_ACCURACY])
152              
153             Each of the results is returned in the form of a string expressing a
154             number as a decimal fraction. These strings are of the type processed
155             by L, and are always returned in L's
156             canonical form.
157              
158             This form of return value is fairly efficient and easy to manipulate.
159             It is convenient both for decimal output and (via implicit coercion to
160             floating point) for low-precision arithmetic. L can be
161             used for high-precision arithmetic. Its resolution is unlimited.
162              
163             =back
164              
165             =head2 Day count conversion
166              
167             =over
168              
169             =item utc_day_to_mjdn(DAY)
170              
171             This function takes a number of days since the TAI epoch and returns
172             the corresponding Modified Julian Day Number (a number of days since
173             1858-11-17 UT). MJDN is a standard numbering for days in Universal Time.
174             There is no bound on the permissible day numbers.
175              
176             =cut
177              
178 3     3   429 use constant _TAI_EPOCH_MJDN => 36204;
  3         7  
  3         495  
179              
180             sub utc_day_to_mjdn($) {
181 3     3 1 1967 my($day) = @_;
182 3         17 return _TAI_EPOCH_MJDN + $day;
183             }
184              
185             =item utc_day_to_cjdn(DAY)
186              
187             This function takes a number of days since the TAI epoch and returns
188             the corresponding Chronological Julian Day Number (a number of days
189             since -4713-11-24). CJDN is a standard day numbering that is useful as
190             an interchange format between implementations of different calendars.
191             There is no bound on the permissible day numbers.
192              
193             =cut
194              
195 3     3   23 use constant _TAI_EPOCH_CJDN => 2436205;
  3         6  
  3         671  
196              
197             sub utc_day_to_cjdn($) {
198 3     3 1 2419 my($day) = @_;
199 3         15 return _TAI_EPOCH_CJDN + $day;
200             }
201              
202             =back
203              
204             =head1 TECHNIQUES
205              
206             There are several interfaces available to determine the time on a
207             computer, and most of them suck. This module will attempt to use the
208             best interface available when it runs. It knows about the following:
209              
210             =over
211              
212             =item ntp_adjtime(), ntp_gettime()
213              
214             These interfaces were devised for Unix systems using the Mills timekeeping
215             model, which is intended for clocks that are synchronised via NTP
216             (the Network Time Protocol). The timekeeping model is detailed in
217             L.
218              
219             These interfaces gives some leap second indications, and an inaccuracy
220             bound on the time returned. Both are faulty in their raw form, but they
221             are corrected by this module. (Those interested in the gory details are
222             invited to read the source.) Resolution 1 us, or on some systems 1 ns.
223              
224             =item GetSystemTimeAsFileTime()
225              
226             This is part of the Win32 API of Microsoft Windows.
227              
228             Misbehaves around leap seconds, and does not give an inaccuracy bound.
229             Resolution of the interface is 100 ns.
230              
231             =item gettimeofday()
232              
233             This is a long-standing Unix interface, so named because it was the
234             interface to the "time-of-day clock".
235              
236             Misbehaves around leap seconds, and does not give an inaccuracy bound.
237             Resolution 1 us.
238              
239             =item Time::Unix::time()
240              
241             This is derived from the original Unix C function, which was
242             also adopted by the C library standard and by Perl. Various systems
243             have different epochs and resolutions for the C function, so
244             it is not usable by this module on its own. The C module
245             corrects for the varying epochs across OSes.
246              
247             Misbehaves around leap seconds, and does not give an inaccuracy bound.
248             Resolution 1 s.
249              
250             =back
251              
252             The author would welcome patches to this module to make use of
253             high-precision interfaces, along the lines of C, on
254             non-Unix operating systems.
255              
256             =head1 OS-SPECIFIC NOTES
257              
258             The author would appreciate reports of experiences with this module
259             under OSes not listed in this section.
260              
261             =head2 Cygwin
262              
263             Uses gettimeofday(), which gives resolution 1 us but no uncertainty
264             bound and is discontinuous at leap seconds. There is no interface that
265             supplies an uncertainty bound or correct leap second handling.
266              
267             =head2 FreeBSD
268              
269             Experimental code (new in version 0.005) uses the FreeBSD variation of
270             ntp_gettime(), which gives resolution 1 us or 1 ns (depending on system
271             configuration) and uncertainty bound. Please report experiences with
272             this code to the author.
273              
274             =head2 Linux
275              
276             Uses ntp_adjtime(), which gives resolution 1 us and uncertainty bound.
277              
278             =head2 Solaris
279              
280             Uses ntp_gettime(), which gives resolution 1 us and uncertainty bound.
281              
282             =head2 Windows
283              
284             Experimental code (new in version 0.007) uses the native
285             GetSystemTimeAsFileTime(). Observed clock resolution is 10 ms, but
286             lower-order digits are supplied (filled with noise) down to the API
287             resolution of 100 ns. There is no uncertainty bound, and there are
288             discontinuities at leap seconds. There is no interface that supplies
289             an uncertainty bound or correct leap second handling.
290              
291             =head1 SEE ALSO
292              
293             L,
294             L
295              
296             =head1 AUTHOR
297              
298             Andrew Main (Zefram)
299              
300             =head1 COPYRIGHT
301              
302             Copyright (C) 2006, 2007, 2009, 2010, 2012, 2017
303             Andrew Main (Zefram)
304              
305             =head1 LICENSE
306              
307             This module is free software; you can redistribute it and/or modify it
308             under the same terms as Perl itself.
309              
310             =cut
311              
312             1;