MirBSD manpage: mirtime(3), mirtime_daylength(3), mirtime_getleaps(3), mirtime_isleap(3), mjd2timet(3), mjd_explode(3), mjd_implode(3), posix2timet(3), timet2mjd(3), timet2posix(3), timet2tm(3), tm2timet(3)

MIRDATE(3)                 BSD Programmer's Manual                  MIRDATE(3)

NAME

     mirtime_daylength, mirtime_getleaps, mirtime_isleap, timet2posix,
     posix2timet, timet2mjd, mjd2timet, timet2tm, tm2timet, mjd_explode,
     mjd_implode - MirBSD time API

SYNOPSIS

     int
     mirtime_daylength(time_t mjdday);
     // mjdday must be in [MJD_MIN; MJD_MAX]

     const time_t *
     mirtime_getleaps(void);

     int
     mirtime_isleap(time_t t);

     time_t
     timet2posix(time_t t);

     time_t
     posix2timet(time_t t);
     // t must be in [TIME_MIN; TIMET_POSIX_MAX]

     mirtime_mjd *
     timet2mjd(mirtime_mjd *mjd, time_t t);

     time_t
     mjd2timet(mirtime_mjd *mjd);
     // mjd->mjd must be in [MJD_MIN; MJD_MAX] or see below
     // mjd->sec must be in [0; 86399] or 86400 if leap

     struct tm *
     timet2tm(struct tm *dst, time_t src);

     time_t
     tm2timet(struct tm *src);
     // constraints tbd

     struct tm *
     mjd_explode(struct tm *tm, mirtime_mjd *mjd);

     mirtime_mjd *
     mjd_implode(mirtime_mjd *mjd, struct tm *tm);
     // constraints tbd

DESCRIPTION

     The mirtime_daylength() function returns the length of mjdday in seconds
     (86400 or, if leap, 86401) or 0 (if the argument was out of bounds).

     The mirtime_getleaps() function returns a pointer (which is guaranteed to
     be not NULL) to a read-only array of time_t values that are positive leap
     seconds, terminated by a value of 0. These functions use a table which
     should be initialised with tzset() before using chroot(2) or a similar
     mechanism. The mirtime_isleap() function returns 1 if t is known to be a
     leap second, 0 otherwise. Both use the leap second-aware time_t scale.

     The remaining functions mentioned convert time values between a broken-
     down calendar date struct tm, a Modified Julian Date mirtime_mjd, seconds
     since the First of January, 1970, midnight UTC time_t, and POSIX time
     (seconds since the epoch, 86400 seconds per day, also stored in time_t).

     mjd_implode() and tm2timet() parse the fields tm_sec, tm_min, tm_hour,
     tm_mday, tm_mon, tm_year, tm_gmtoff of struct tm; mjd_explode() and
     timet2tm() fill in 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 nil values.

     Use these functions, macros and types on MirBSD by including <sys/time.h>
     and/or <time.h> under _ALL_SOURCE; test for SYSKERN_MIRTIME_H.

TYPES

     time_t is a signed integral type of 32 or 64 bit, machine-dependent.
     Currently, it is signed long long on all MirBSD platforms. Other systems
     may have different-sized, unsigned, or even floating point(!) time_t.

     struct tm consists of the following slots:

           int tm_sec;             /* seconds [0-60] */
           int tm_min;             /* minutes [0-59] */
           int tm_hour;            /* hours [0-23] */
           int tm_mday;            /* day of month [1-31] */
           int tm_mon;             /* month of year - 1 [0-11] */
           int tm_year;            /* years since 1900 */
           int tm_wday;            /* day of week [0-6] (0=Sunday) OUT */
           int tm_yday;            /* day of year [0-365] OUT */
           int tm_isdst;           /* summer time? [<0 unknown, 0 no, >0 yes] */
           long tm_gmtoff;         /* seconds offset from UTC to the east */
           char *tm_zone;          /* abbreviation of timezone name OUT */

     mirtime_mjd consists of the following slots:

           time_t mjd;             /* days since 1858-11-17, JD 2'400'000.5 */
           int sec;                /* (UTC) seconds into that day [0-86400] */

     Functions are not required to handle out-of-bounds sec because 86400 is
     special; mirtime_mjd must thus be normalised on pain of UB. One function
     historically permitted unsafe out-of-range sec values but no longer does.
     mjd must be an integral number even if time_t is a floating point type.

CONSTRAINTS

     You can calculate safe values with the following formulae:

           TIMET_POSIX_MAX = timet2posix(TIME_MAX)
           MJD_MAX = (timet2posix(TIME_MAX - 1) - 86399) / 86400 + 40587
           MJD_MIN = TIME_MIN / 86400 + 40587

     Note that TIME_MAX and TIME_MIN are type-dependent and not provided by
     the supplied header files. MJD_MIN is a compile-time constant but MJD_MAX
     & TIMET_POSIX_MAX are run-time constants; the leap second table is ini-
     tialised by mirtime_getleaps(), timet2posix(...), or (on MirBSD) tzset().

     mjd2timet() accepts certain cases where mjd->mjd is either (MJD_MAX + 1)
     or (MJD_MIN - 1), but not with all possible mjd->sec values. To obtain
     permitted ranges use timet2mjd(mjd, TIME_MAX) (or TIME_MIN) if necessary.

ERRORS

     Some error conditions may raise an implementation-defined signal caused
     by signed integer truncation instead of returning an error indicator.

     mirtime_getleaps() does not report to the application; if the table is
     empty, either the system does not use leap seconds or an error occurred.
     It always succeeds, as does mirtime_isleap() as well as timet2mjd().

     If the result is not representable in the output, mjd_explode() and thus
     timet2tm() truncate tm_year to INT_MAX (or INT_MIN) and return NULL; out-
     of-range data has mirtime_daylength() return 0 and posix2timet() return a
     value lower than the input (actually 0); timet2posix() always succeeds at
     this time but the introduction of negative leap seconds may change this.

     If the input was out of bounds or the result is not representable, XXX
     mjd_implode() raises an implementation-defined signal (caused by signed
     time_t integer truncation) or returns NULL; mjd2timet(), and tm2timet()
     thus, raise that signal or return (time_t)-1 setting errno to EOVERFLOW.

SEE ALSO

     chroot(2), mktime(3), tzset(3)

STANDARDS

     This set of functions expects your operating system to not conform to
     IEEE Std 1003.1 ("POSIX.1") for correct time_t handling.

HISTORY

     This API replaced a DJB-inspired TAI API with MirBSD #11.

AUTHORS

     mirabilos <m@mirbsd.org>

CAVEATS

     This API requires an int with at least 18 bit precision. Internal to the
     implementation long long must be wider than int. XXX tbd, also, int must
     fit into time_t now. XXX If int is wider than time_t, putting values not
     fitting into time_t in int fields or int function parameters will invoke
     Undefined Behaviour. Most arithmetic is unchecked if time_t is a floating
     point type.

     mjd_implode() requires the combination of tm_hour, tm_min, tm_sec and
     tm_gmtoff to fit in an int; given the types above, it is safe if time_t
     is >= 8 bit wider than int; else call mjd_explode(.day=TIME_MAX) and
     mjd_explode(.day=TIME_MIN) to obtain permissible value ranges. tm2timet()
     chains mjd_implode() to mjd2timet().

     Before 2022, error handling was lacking or outright missing.

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 (other than
     contrib/code/Snippets/posixtz.c). It's probably better this way, though.

     This code will cause compiler warnings on platforms with unsigned time_t
     but probably run; I'm not so sure if the same is true for platforms where
     it is a floating point type... same if type widths are unusual...

MirBSD #10-current               May 27, 2022                                2

Generated on 2022-12-24 01:00:14 by $MirOS: src/scripts/roff2htm,v 1.113 2022/12/21 23:14:31 tg Exp $ — This product includes material provided by mirabilos.

These manual pages and other documentation are copyrighted by their respective writers; their sources are available at the project’s CVSweb, AnonCVS and other mirrors. The rest is Copyright © 2002–2022 MirBSD.

This manual page’s HTML representation is supposed to be valid XHTML/1.1; if not, please send a bug report — diffs preferred.

Kontakt / Impressum & Datenschutzerklärung