Time::TAI::Now - determine current time in TAI


    use Time::TAI::Now qw(
        now_tai_rat now_tai_gsna now_tai_flt now_tai_dec);

    ($instant, $bound) = now_tai_rat;
    ($instant, $bound) = now_tai_rat(1);
    ($instant, $bound) = now_tai_gsna;
    ($instant, $bound) = now_tai_gsna(1);
    ($instant, $bound) = now_tai_flt;
    ($instant, $bound) = now_tai_flt(1);
    ($instant, $bound) = now_tai_dec;
    ($instant, $bound) = now_tai_dec(1);


This module is one answer to the question "what time is it?". It determines the current time on the TAI scale, and puts a bound on how inaccurate it could be. It is designed to interoperate with Time::TAI, which knows all about the TAI time scale.

TAI (International Atomic Time) is a time scale produced by an ensemble of atomic clocks around Terra. It attempts to tick at the rate of proper time on the Terran geoid (i.e., at sea level). It is the frequency standard underlying Coordinated Universal Time (UTC).

TAI is not connected to planetary rotation, and so has no inherent concept of a "day" or of "time of day". (There is nevertheless a convention for how to represent TAI times using day-based notations, for which see Time::TAI.) This module represents instants on the TAI time scale as a scalar number of TAI seconds since its epoch, which was at 1958-01-01T00:00:00.0 UT2 as calculated by the United States Naval Observatory. This matches the convention used by Time::TAI.


Each of these functions determines the current TAI time and returns it. They vary in the form in which the time is returned. In each case, the function returns a list of two values. The first value identifies a current TAI instant, in the form of a number of seconds since the TAI epoch. The second value is an inaccuracy bound, as a number of seconds, or undef if no accurate answer could be determined.

If an inaccuracy bound is returned then the function is claiming to have answered correctly, to within the specified margin. That is, some instant during the execution of the function is within the specified margin of the instant identified. (This semantic differs from older current-time interfaces that are content to return an instant that has already passed.) The inaccuracy bound describes the actual time represented in the first return value, not some internal value that was rounded to generate the return value.

The inaccuracy bound is measured in TAI seconds; that is, in SI seconds on the Terran geoid as realised by atomic clocks. This differs from SI seconds at the computer's location, but the difference is only apparent if the computer hardware is significantly time dilated with respect to the geoid.

If undef is returned instead of an inaccuracy bound then the function could not find a trustable answer. Either the clock available was not properly synchronised or its accuracy could not be established. Whatever time could be found is returned, but the function makes no claim that it is accurate. It should be treated with suspicion. In practice, clocks of this nature are especially likely to misbehave around UTC leap seconds.

Each function will die if it can't find a plausible time at all. If the DEMAND_ACCURACY parameter is supplied and true then it will also die if it could not find an accurate answer, instead of returning with undef for the inaccuracy bound.


Both return values are in the form of Math::BigRat objects.

This retains full resolution, is future-proof, and is easy to manipulate, but beware that Math::BigRat is currently rather slow. If performance is a problem then consider using one of the functions below that return the results in other formats.


The time since the epoch and the inaccuracy bound (if present) are each returned in the form of a four-element array, giving a high-resolution fixed-point number of seconds. The first element is the integral number of gigaseconds, the second is an integral number of seconds in the range [0, 1000000000), the third is an integral number of nanoseconds in the same range, and the fourth is an integral number of attoseconds in the same range.

This form of return value is fairly efficient. It is convenient for decimal output, but awkward to do arithmetic with. Its resolution is adequate for the foreseeable future, but could in principle be obsoleted some day.

The number of gigaseconds will exceed 1000000000, thus violating the intent of the number format, one exasecond after the epoch, when the universe is around three times the age it had at the epoch. Terra (and thus TAI) might still exist then, depending on how much its orbital radius increases before Sol enters its red giant phase. In that situation the number of gigaseconds will simply continue to increase, ultimately overflowing if native integer formats don't grow, though it's a good bet that they will.


Both return values are in the form of Perl floating point numbers.

This form of return value is very efficient and easy to manipulate. However, its resolution is limited, rendering it already obsolete for high-precision applications at the time of writing.


Each return value is in the form of a string expressing a number as a decimal fraction. These strings are of the type processed by Math::Decimal, and are always returned in Math::Decimal's canonical form.

This form of return value is fairly efficient and easy to manipulate. It is convenient both for decimal output and (via implicit coercion to floating point) for low-precision arithmetic. Math::Decimal can be used for high-precision arithmetic. Its resolution is unlimited.


Time::TAI, Time::UTC::Now


Andrew Main (Zefram) <>


Copyright (C) 2006, 2009, 2010, 2017 Andrew Main (Zefram) <>


This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself.