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 5     5   238898 { use 5.006; }
  5         15  
58 5     5   21 use warnings;
  5         7  
  5         110  
59 5     5   18 use strict;
  5         10  
  5         176  
60              
61             our $VERSION = "0.013";
62              
63 5     5   1199 use parent "Exporter";
  5         1164  
  5         23  
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 5     5   410 use constant _TAI_EPOCH_MJDN => 36204;
  5         7  
  5         473  
179              
180             sub utc_day_to_mjdn($) {
181 3     3 1 1054 my($day) = @_;
182 3         9 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 5     5   27 use constant _TAI_EPOCH_CJDN => 2436205;
  5         8  
  5         424  
196              
197             sub utc_day_to_cjdn($) {
198 3     3 1 1057 my($day) = @_;
199 3         9 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             in descending order of preference:
210              
211             =over
212              
213             =item ntp_adjtime(), ntp_gettime(), adjtimex()
214              
215             These interfaces were devised for Unix systems using the Mills timekeeping
216             model, which is intended for clocks that are synchronised via NTP
217             (the Network Time Protocol). The timekeeping model is detailed in
218             L.
219              
220             These interfaces gives some leap second indications, and an inaccuracy
221             bound on the time returned. Both are faulty in their raw form, but they
222             are corrected by this module. (Those interested in the gory details are
223             invited to read the source.) Resolution 1 us, or on some systems 1 ns.
224              
225             =item clock_gettime(CLOCK_UTC)
226              
227             This is a proposed interface for relatively simple (simpler than the
228             NTP interface) acquisition of precise real time. It is defined by
229             L.
230              
231             This interface gives an explicit leap second indication, and so permits
232             this module to correctly tick through leap seconds. It also provides
233             a limited kind of inaccuracy bound: it will only provide a reading at
234             all if it is thought to be accurate to within a second. No tighter
235             inaccuracy bound can be given. Resolution 1 ns.
236              
237             =item clock_gettime(CLOCK_REALTIME)
238              
239             This is a POSIX interface.
240              
241             Misbehaves around leap seconds, and does not give an inaccuracy bound.
242             Resolution 1 ns.
243              
244             =item GetSystemTimeAsFileTime()
245              
246             This is part of the Win32 API of Microsoft Windows.
247              
248             Misbehaves around leap seconds, and does not give an inaccuracy bound.
249             Resolution of the interface is 100 ns.
250              
251             =item gettimeofday()
252              
253             This is a long-standing Unix interface, so named because it was the
254             interface to the "time-of-day clock".
255              
256             Misbehaves around leap seconds, and does not give an inaccuracy bound.
257             Resolution 1 us.
258              
259             =item Time::Unix::time()
260              
261             This is derived from the original Unix C function, which was
262             also adopted by the C library standard and by Perl. Various systems
263             have different epochs and resolutions for the C function, so
264             it is not usable by this module on its own. The C module
265             corrects for the varying epochs across OSes.
266              
267             Misbehaves around leap seconds, and does not give an inaccuracy bound.
268             Resolution 1 s.
269              
270             =back
271              
272             The author would welcome patches to this module to make use of
273             high-precision interfaces, along the lines of C, on
274             non-Unix operating systems.
275              
276             =head1 OS-SPECIFIC NOTES
277              
278             The author would appreciate any new information for this section,
279             especially reports of experiences with this module under OSes not listed
280             in this section.
281              
282             =head2 Cygwin
283              
284             Uses clock_gettime(CLOCK_REALTIME). Actual clock resolution undetermined,
285             but probably resembles what is seen on native Windows (discussed below).
286             There is no uncertainty bound, and there are discontinuities at leap
287             seconds. There is no interface that supplies an uncertainty bound or
288             correct leap second handling.
289              
290             =head2 FreeBSD
291              
292             Uses ntp_gettime(), which gives resolution 1 us or 1 ns (depending on
293             system configuration) and uncertainty bound.
294              
295             Kernel bug #42089 causes ntp_gettime() on affected systems to denominate
296             time in nanoseconds regardless of the configured resolution. Outside
297             the first millisecond of each second, this provides an out-of-range
298             microseconds count, which this module detects and rejects, falling
299             back to clock_gettime(CLOCK_REALTIME) or gettimeofday() (thus getting
300             no uncertainty bound and discontinuities at leap seconds). Inside the
301             first millisecond of each second, ntp_gettime()'s response looks correct
302             and is accepted, yielding incorrect time (ranging over the whole second)
303             with an uncertainty bound that is insufficient to cover this inaccuracy.
304             It is infeasible for this module to detect that the time is affected by
305             this bug. The bug can be avoided on any particular host by configuring
306             it for nanosecond resolution.
307              
308             =head2 Linux
309              
310             Uses ntp_adjtime(), which gives resolution 1 us or 1 ns (depending on
311             system configuration) and uncertainty bound.
312              
313             =head2 Solaris
314              
315             Uses ntp_gettime(), which gives resolution 1 us and uncertainty bound.
316              
317             =head2 Windows
318              
319             Effectively uses the native GetSystemTimeAsFileTime().
320             (Some versions of Windows provide the POSIX clock_gettime(CLOCK_REALTIME)
321             interface, which will be used in preference, but it actually provides
322             access to the same functionality.)
323             Observed clock resolution is 10 ms, but
324             lower-order digits are supplied (filled with noise) down to the API
325             resolution of 100 ns. There is no uncertainty bound, and there are
326             discontinuities at leap seconds. There is no interface that supplies
327             an uncertainty bound or correct leap second handling.
328              
329             =head1 SEE ALSO
330              
331             L,
332             L
333              
334             =head1 AUTHOR
335              
336             Andrew Main (Zefram)
337              
338             =head1 COPYRIGHT
339              
340             Copyright (C) 2006, 2007, 2009, 2010, 2012, 2017
341             Andrew Main (Zefram)
342              
343             =head1 LICENSE
344              
345             This module is free software; you can redistribute it and/or modify it
346             under the same terms as Perl itself.
347              
348             =cut
349              
350             1;