Permission to use, copy, modify, and distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
$Id: isc_time.3,v 1.7 2001/01/09 21:48:38 bwelling Exp $
.Dd Jun 30, 2000 .Dt ISC_TIME 3 .Os BIND9 9 .Sh NAME .Nm isc_interval_iszero , .Nm isc_time_set , .Nm isc_time_settoepoch , .Nm isc_time_isepoch , .Nm isc_time_now , .Nm isc_time_nowplusinterval , .Nm isc_time_compare , .Nm isc_time_add , .Nm isc_time_subtract , .Nm isc_time_microdiff , .Nm isc_time_seconds , .Nm isc_time_secondsastimet , .Nm isc_time_nanoseconds .Nd time-related operations .Sh SYNOPSIS .Fd #include <config.h> .Fd #include <errno.h> .Fd #include <limits.h> .Fd #include <time.h> .Fd #include <sys/time.h> .Fd #include <isc/string.h> .Fd #include <isc/time.h> .Fd #include <isc/util.h> .Ft void .Fo "isc_interval_set" .Fa "isc_interval_t *i" .Fa "unsigned int seconds" .Fa "unsigned int nanoseconds" .Fc .Ft isc_boolean_t .Fo isc_interval_iszero .Fa "isc_interval_t *" .Fc .Ft void .Fo isc_time_set .Fa "isc_time_t *t" .Fa "unsigned int seconds" .Fa "unsigned int nanoseconds" .Fc .Ft void .Fo isc_time_settoepoch .Fa "isc_time_t *t" .Fc .Ft isc_boolean_t .Fo isc_time_isepoch .Fa "isc_time_t *t" .Fc .Ft isc_result_t .Fo isc_time_now .Fa "isc_time_t *t" .Fc .Ft isc_result_t .Fo isc_time_nowplusinterval .Fa "isc_time_t *t" .Fa "isc_interval_t *i" .Fc .Ft int .Fo isc_time_compare .Fa "isc_time_t *t1" .Fa "isc_time_t *t2" .Fc .Ft isc_result_t .Fo isc_time_add .Fa "isc_time_t *t" .Fa "isc_interval_t *i" .Fa "isc_time_t *result" .Fc .Ft isc_result_t .Fo isc_time_subtract .Fa "isc_time_t *t" .Fa "isc_interval_t *i" .Fa "isc_time_t *result" .Fc .Ft isc_uint64_t .Fo isc_time_microdiff .Fa "isc_time_t *t1" .Fa "isc_time_t *t2" .Fc .Ft isc_uint32_t .Fo isc_time_seconds .Fa "isc_time_t *t" .Fc .Ft isc_result_t .Fo isc_time_secondsastimet .Fa "isc_time_t *t" .Fa "time_t *secondsp" .Fc .Ft isc_uint32_t .Fo isc_time_nanoseconds .Fa "isc_time_t *t" .Fc .Sh DESCRIPTION These functions are used by the name server for any time-related activities. They operate on the system's struct .Dv time_t and two local data structures: d -literal -offset indent struct isc_interval { unsigned int seconds; unsigned int nanoseconds; }; typedef struct isc_interval isc_interval_t; .Ed d -literal -offset indent struct isc_time { unsigned int seconds; unsigned int nanoseconds; }; typedef struct isc_time isc_time_t; .Ed The contents of these structures are private and MUST NOT be accessed by callers directly. Details have only been provided so that callers can avoid dynamic allocation. The elements of these structures should only be manipulated via the following functions.
p The function .Fn isc_interval_set initialises the .Dv isc_interval_t pointed at by .Fa *i . The elements .Dv seconds and .Dv nanoseconds are set to the values of .Fa seconds and .Fa nanoseconds respectively.
p .Fn isc_interval_iszero returns .Er ISC_TRUE if .Fa *i is the zero interval. This condition should hold when the desired amount of time until an event associated with interval .Fa *i has elapsed.
p .Fn isc_time_settoepoch sets .Fa *t to the time of the epoch. On x systems this is 0 hours, 0 minutes, 0 seconds, January 1, 1970 UTC.
p The function .Fn isc_time_isepoch returns .Er ISC_TRUE if the time in .Fa *t is equal to the epoch time: "time zero". It returns .Er ISC_FALSE otherwise.
p The current absolute time of day is obtained from .Fn isc_time_now . On a successful call to this function, the structure pointed at by .Fa *t is set to the number of seconds and nanoseconds since the epoch.
p .Fn isc_time_nowplusinterval sets .Fa *t to the current time plus the interval specified in .Fa *i .
p .Fn isc_time_compare compares the times referenced by .Fa *t1 and .Fa *t2 . It returns 0 if the two times are equal. A value of 1 is returned when .Fa *t1 is greater than .Fa *t2 . If .Fa *t1 is less than .Fa *t2 .Fn isc_time_compare returns -1.
p The function .Fn isc_time_add adds .Fa *i to .Fa *t and .Fa *result . The converse operation is performed by .Fa isc_time_subtract . It subtracts .Fa *i from .Fa *t and stores the result in .Fa result .
p .Fn isc_time_microdiff returns the number of difference in microseconds between .Fa *t1 and .Fa *t2. Zero is returned if the time represented by .Fa *t1 is less than that given by .Fa t2 .
p .Fn isc_time_seconds and .Fn isc_time_nanoseconds return the number of seconds and nanoseconds respectively in the time indicated by .Fa *t .
p The function .Fn isc_time_secondsastimet converts the time value represented by .Fa *t to the system's .Dv time_t struct pointed at by .Fa *secondsp . It takes great care to ensure that the number of seconds represented by .Dv t->seconds can be represented by a .Dv time_t . This is not as straightforward as it might seem because a .Dv time_t might not be an integral type. Implementations may treat this type as a signed or unsigned quantity which potentially creates sign extension problems. .Sh RETURN VALUES .Fn isc_time_now and .Fn isc_time_nowplusinterval return .Er ISC_R_UNEXPECTED if they are unable to get the time of day or if the operating system returns nonsense. They return .Er ISC_R_RANGE if the number of seconds returned by the operating system is too big to fit in a .Dv "unsigned int" . A result of .Er ISC_R_SUCCESS is returned when the functions are successful.
p Calls to .Fn isc_time_add , .Fn isc_time_subtract and .Fn isc_time_secondsastimet normally return .Er ISC_R_SUCCESS . .Fn isc_time_add returns .Er ISC_R_RANGE if the addition of the time values represented by .Fa t and .Fa i result in a number of seconds that are too big to fit in a .Dv "unsigned int" quantity. If the time value given by .Fa i is less than that in .Fa t , .Er ISC_R_RANGE is returned by .Fn isc_time_subtract . .Er ISC_R_RANGE is returned by .Fn isc_time_secondsastimet when the number of seconds represented by .Dv t->seconds cannot be represented by the operating system's .Dv time_t type. .Sh SEE ALSO .Xr gettimeofday 2 , .Xr getitimer 2 , .Xr ctime 3 .Sh BUGS Nanosecond and microsecond resolution time values are notoriously inaccurate on most x systems because few, if any, of them have hardware or software which provides that level of precision. Consult the vendor's documentation. The resolution of the real-time clock in most systems is typically 100Hz which means the finest granularity of time-related activity is at most 0.01 seconds. Scheduling latency and process or thread context switching can also delay the processing of real-time events. For most DNS activity such as decrementing TTLs or zone refreshes, this loss of accuracy is not significant.
p The accuracy of absolute times returned by .Fn isc_time_now and .Fn isc_time_nowplusinterval depend on the reliability of the system's time of day clock. This should be synchronised to UTC using an external time source using a good timekeeping protocol such as NTP. Pedants might want to worry about whether the absolute time includes leap seconds or not.