libstddjb
skalibs
skalibs
Software
skarnet.org

# The `djbtime` library interface

The following functions are declared in the `skalibs/djbtime.h` header, and implemented in the `libskarnet.a` or `libskarnet.so` library.

## General information

`djbtime` is a set of functions to convert tai and tain structures, and TAI time, from and to other time formats and user-friendly representations.

## Data structures

- TAI time with 1-second precision is represented as a tai.
- TAI time with more precision is represented as a tain.
- UTC time is represented as an unsigned 64-bit integer equal to 2^62 added to the number of seconds since the Epoch. It's a trivial extension of the standard 32-bit Unix time that will expire in 2038.
- Broken-down GMT or local time with more than a 1-second precision is stored in a `localtmn` structure, containing a `struct tm` tm field and an unsigned long nano field.

## Functions

### UTC

`int utc_from_tai (uint64_t *u, tai const *t)`
Converts the absolute TAI64 time in *t to an UTC time, stored in *u as an unsigned 64-bit integer. *u is actually 2^62 plus the number of seconds since the Epoch. The function returns 1 if it succeeds, or 0 (and sets errno) if an error occurs. If *t happens to hit a leap second, the function returns 2 instead of 1.

`int tai_from_utc (tai *t, uint64_t u)`
Converts the UTC time in u, stored as an unsigned 64-bit integer (2^62 plus the number of seconds since the Epoch), to a TAI64 time in *t. The function returns 1 if it succeeds, or 0 (and sets errno) if an error occurs.

### NTP

`int ntp_from_tain (uint64_t *ntp, tain const *a)`
Converts the absolute TAI64N time in *a to a 64-bit NTP timestamp, stored in *ntp. The higher 32 bits of *ntp represent a number of seconds ; the lower 32 bits are the fractional part of the timestamp. The function returns 1 if it succeeds, or 0 (and sets errno) if an error occurs (for instance: *a cannot be represented in the valid NTP range).

`int tain_from_ntp (tain *a, uint64_t ntp)`
Converts the NTP timestamp in ntp to a TAI64N time in *a. The function returns 1 if it succeeds, or 0 (and sets errno) if an error occurs.

### Local time

The following functions convert time between an internal representation and a broken-down `struct tm`. Conversions are performed to get leap seconds handling right, depending on whether skalibs has been configured for a TAI-10 or a UTC system clock, and on whether the current timezone takes leap seconds into account or not.

`int localtm_from_tai (struct tm *tm, tai const *t, int lo)`
Converts the TAI time in *t to broken-down GMT (if lo is zero) or local (if lo is nonzero) time in *tm. The function returns 1 if it succeeds, or 0 (and sets errno) if an error occurs (for instance: *t cannot be validly represented in a struct tm). If *t happens to hit a leap second, the value of tm→tm_sec is 60.

`int localtm_from_utc (struct tm *tm, uint64_t u, int lo)`
Converts the UTC time in u to broken-down GMT (if lo is zero) or local (if lo is nonzero) time in *tm. The function returns 1 if it succeeds, or 0 (and sets errno) if an error occurs (for instance: u cannot be validly represented in a struct tm).

`int localtm_from_sysclock (struct tm *tm, uint64_t u, int lo)`
Converts the time in u to broken-down GMT (if lo is zero) or local (if lo is nonzero) time in *tm. u will be interpreted as a TAI-10 value (with `--enable-tai-clock`) or as a UTC value (without `--enable-tai-clock`). The function returns 1 if it succeeds, or 0 (and sets errno) if an error occurs (for instance: u cannot be validly represented in a struct tm).

`int utc_from_localtm (uint64_t *u, struct tm const *tm)`
Converts the broken-down local time in *tm to an UTC value in *u. The function returns 1 if it succeeds, or 0 (and sets errno) if an error occurs.

`int tai_from_localtm (tai *t, struct tm const *tm)`
Converts the broken-down local time in *tm to a TAI value in *t. The function returns 1 if it succeeds, or 0 (and sets errno) if an error occurs.

`int sysclock_from_localtm (uint64_t *u, struct tm const *tm)`
Converts the broken-down local time in *tm to a value in *u - either TAI-10 or UTC depending on your system clock. The function returns 1 if it succeeds, or 0 (and sets errno) if an error occurs.

The following functions use the `localtmn` type to hold both a broken-down time and a nanosecond count:

    typedef struct localtmn_s localtmn, *localtmn_ref ;
    struct localtmn_s
    {
      struct tm tm ;
      uint32_t nano ;
    } ;

The prototypes are self-explaining:

`int localtmn_from_tain (localtmn *tmn, tain const *a, int lo) ;
int tain_from_localtmn (tain *a, localtmn const *tmn) ;
int localtmn_from_sysclock (localtmn *tmn, tain const *a, int lo) ;
int sysclock_from_localtmn (tain *a, localtmn const *tmn) ;`