TAITIME(3) BSD Programmer's Manual TAITIME(3)NAME
tai_leaps, tai_isleap, timet2tai, tai2timet, utc2tai, tai2utc, mjd2tai,
tai2mjd, mjd2tm, tm2mjd, tai_time, taina_time, exporttai, importtai-
year-2038-safe leap second compliant 64 bit time functions
SYNOPSIS
#include <sys/types.h>
#include <sys/taitime.h>
tai64_t
tai_time(tai64_t *t);
void
taina_time(tai64na_t *t);
tai64_t *
tai_leaps(void);
int
tai_isleap(tai64_t t);
tai64_t
timet2tai(time_t tv);
time_t
tai2timet(tai64_t t);
tai64_t
utc2tai(int64_t t);
int64_t
tai2utc(tai64_t t);
tai64_t
mjd2tai(mjd_t mjd);
mjd_t
tai2mjd(tai64_t t);
struct tm
mjd2tm(mjd_t mjd);
mjd_t
tm2mjd(struct tm tm);
void
exporttai(u_int8_t *dst, tai64na_t *src);
void
importtai(u_int8_t *src, tai64na_t *dst);
DESCRIPTION
The tai_time() and taina_time() functions return the current time in the
TAI64 format into the tai64_t or tai64na_t variable pointed to by the t
argument, if the argument is not NULL. Additionally, tai_time() returns
the value.
The tai64_t and tai64na_t data types are specified further below.
The tai_leaps() function returns a pointer, which is guaranteed to be not
NULL, to a zero-terminated array of tai64_t values, each denoting a posi-
tive leap second. DJB says, negative leap seconds are not likely to hap-
pen; if they should, a new interface will be published. This function
uses a table which should be initialised with tzset() beforehand if
mechanisms such as chroot(2) are employed.
The tai_isleap() function returns 1 if t is known to be a (positive) leap
second, 0 if otherwise.
The timet2tai() and tai2timet() routines convert their argument between
the TAI64 format and the time_t data type which is generally used in time
keeping, for example by the gettimeofday(2) system call. Generally speak-
ing, a time_t counts the number of real seconds that have happened since
January 1, 1970, 00:00:00 UTC (coordinated universal time).
The utc2tai() and tai2utc() functions convert between the TAI64 format
and an UTC value expressed as int64_t. The UTC value equals the time_t
value as shown above, with the difference that not real seconds are
counted, but seconds that would have happened if every full day had ex-
actly 86400 seconds. Because there are leap seconds, in reality some days
have 86401 and some 86399 seconds, that's why this format cannot be used
for reliable time keeping (it is being used by the NTP protocol), but
it's useful for conversion between calendar dates and second-counting
dates. IEEE Std 1003.1 ("POSIX") compliant systems, unlike MirOS, force
their time_t type and internal kernel time to be in this format, com-
pletely ignoring the existence of leap seconds.
The mjd2tai() and tai2mjd() functions convert between the TAI64 type and
the MJD structure described further below, which keeps time in a calendar
format.
The mjd2tm() and tm2mjd() functions convert between the MJD structure and
the more common struct tm as used by mktime(3). tm2mjd() converts the
fields tm_sec, tm_min, tm_hour, tm_mday, tm_mon, tm_year, tm_gmtoff of
struct tm; mjd2tm() fills the fields tm_sec, tm_min, tm_hour, tm_mday,
tm_mon, tm_year, tm_wday, tm_yday with sensible values and tm_isdst,
tm_gmtoff, tm_zone with null values.
The exporttai() and importtai() functions convert between internal
TAI64NA format and DJB-compatible on-the-wire TAI64NA/TAICLOCK format.
See below for further documentation.
The functions and data types described above are defined in the <time.h>
header file. The data type tai64_t is aliased to int64_t. The data type
tai64na_t includes the following fields:
tai64_t secs; /* seconds (see below) */
uint32_t nano; /* nanoseconds */
uint32_t atto; /* attoseconds */
The data type mjd_t includes the following fields:
time_t mjd; /* day of modified julian calendar */
int32_t sec; /* second within the day */
FILES
/usr/share/zoneinfo time zone information directory
/usr/share/zoneinfo/UTC default source of leap second information
/usr/share/zoneinfo/posixrules alternative source of leap second infor-
mation, if UTC is absent.
SEE ALSOchroot(2), gettimeofday(2), mktime(3), ntpd(8), tzset(3)STANDARDS
This set of functions expects your operating system to not conform to
IEEE Std 1003.1 ("POSIX") for correct time_t handling.
The exported TAI64NA datatype and the TAI64 second offset have been stan-
dardised by Dan J. Bernstein, see http://cr.yp.to/proto/utctai.html for a
general overview of UTC, TAI and the NTP/POSIX problems,
http://cr.yp.to/libtai/tai64.html for the various data types and
http://cr.yp.to/proto/taiclock.txt for the specification of the on-wire
TAICLOCK format, which contains the result of the exporttai() function in
bytes 4 to 19.
HISTORY
The TAI function suite appeared in MirOS #8.
AUTHORS
The original author of the TAI64 data types and the libtai library for
TAI64 manipulation, which was placed into public domain, is Dan J.
Bernstein <djb@cr.yp.to>.
The libc implementation of TAI64 functions are authored by
Thorsten "mirabilos" Glaser <tg@mirbsd.org>.
CAVEATS
The libc TAI functions have different function names and data types (ex-
cept the exported TAI64NA on-the-wire format) than the DJB libtai ones.
This allows one to use both libraries at the same time. The functions are
exchangable, it is feasible to patch djb libtai to use this set of func-
tions provided by libc internally.
A tai64_t value is, in contrast to time_t, not zero-based, but has a bias
of __TAI64_BIAS, which is implementation-defined to 0x4000000000000000ULL
for the MirOS operating system. You will have to be extra carefully when
adding values of type tai64_t or storing time values versus time dis-
tances in variables.
BUGS
The leap second table is read from the timezone information file. This
has implications on the location of the file and its up-to-dateness.
There is no method to select POSIX-conformant behaviour. It's probably
better this way, though.
Few sanitising of values is done, but the functions are considered safe.
MirOS BSD #10-current February 7, 2007 2