1*c0b5d9fbSchristos /*	$NetBSD: time.h,v 1.8 2022/09/23 12:15:35 christos Exp $	*/
2e2b1b9c0Schristos 
3e2b1b9c0Schristos /*
4e2b1b9c0Schristos  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
5e2b1b9c0Schristos  *
6*c0b5d9fbSchristos  * SPDX-License-Identifier: MPL-2.0
7*c0b5d9fbSchristos  *
8e2b1b9c0Schristos  * This Source Code Form is subject to the terms of the Mozilla Public
9e2b1b9c0Schristos  * License, v. 2.0.  If a copy of the MPL was not distributed with this
1073584a28Schristos  * file, you can obtain one at https://mozilla.org/MPL/2.0/.
11e2b1b9c0Schristos  *
12e2b1b9c0Schristos  * See the COPYRIGHT file distributed with this work for additional
13e2b1b9c0Schristos  * information regarding copyright ownership.
14e2b1b9c0Schristos  */
15e2b1b9c0Schristos 
16e2b1b9c0Schristos #ifndef ISC_TIME_H
17e2b1b9c0Schristos #define ISC_TIME_H 1
18e2b1b9c0Schristos 
199742fdb4Schristos #include <errno.h>
20f2e20987Schristos #include <inttypes.h>
21f2e20987Schristos #include <stdbool.h>
229742fdb4Schristos #include <time.h>
23e2b1b9c0Schristos #include <windows.h>
24e2b1b9c0Schristos 
25e2b1b9c0Schristos #include <isc/lang.h>
26e2b1b9c0Schristos #include <isc/types.h>
27e2b1b9c0Schristos 
28e2b1b9c0Schristos /***
299742fdb4Schristos  *** POSIX Shims
309742fdb4Schristos  ***/
319742fdb4Schristos 
32fadf0758Schristos struct tm *
33fadf0758Schristos gmtime_r(const time_t *clock, struct tm *result);
349742fdb4Schristos 
35fadf0758Schristos struct tm *
36fadf0758Schristos localtime_r(const time_t *clock, struct tm *result);
37fadf0758Schristos 
38fadf0758Schristos int
39fadf0758Schristos nanosleep(const struct timespec *req, struct timespec *rem);
40fadf0758Schristos 
41fadf0758Schristos typedef uint32_t useconds_t;
42fadf0758Schristos 
43fadf0758Schristos int
44fadf0758Schristos usleep(useconds_t usec);
459742fdb4Schristos 
469742fdb4Schristos /***
47e2b1b9c0Schristos  *** Intervals
48e2b1b9c0Schristos  ***/
49e2b1b9c0Schristos 
50e2b1b9c0Schristos /*
51e2b1b9c0Schristos  * The contents of this structure are private, and MUST NOT be accessed
52e2b1b9c0Schristos  * directly by callers.
53e2b1b9c0Schristos  *
54e2b1b9c0Schristos  * The contents are exposed only to allow callers to avoid dynamic allocation.
55e2b1b9c0Schristos  */
56e2b1b9c0Schristos struct isc_interval {
57f2e20987Schristos 	int64_t interval;
58e2b1b9c0Schristos };
59e2b1b9c0Schristos 
60e2b1b9c0Schristos LIBISC_EXTERNAL_DATA extern const isc_interval_t *const isc_interval_zero;
61e2b1b9c0Schristos 
62e2b1b9c0Schristos /*
63e2b1b9c0Schristos  * ISC_FORMATHTTPTIMESTAMP_SIZE needs to be 30 in C locale and potentially
64e2b1b9c0Schristos  * more for other locales to handle longer national abbreviations when
65e2b1b9c0Schristos  * expanding strftime's %a and %b.
66e2b1b9c0Schristos  */
67e2b1b9c0Schristos #define ISC_FORMATHTTPTIMESTAMP_SIZE 50
68e2b1b9c0Schristos 
69e2b1b9c0Schristos ISC_LANG_BEGINDECLS
70e2b1b9c0Schristos 
71e2b1b9c0Schristos void
729742fdb4Schristos isc_interval_set(isc_interval_t *i, unsigned int seconds,
739742fdb4Schristos 		 unsigned int nanoseconds);
74e2b1b9c0Schristos /*
75e2b1b9c0Schristos  * Set 'i' to a value representing an interval of 'seconds' seconds and
76e2b1b9c0Schristos  * 'nanoseconds' nanoseconds, suitable for use in isc_time_add() and
77e2b1b9c0Schristos  * isc_time_subtract().
78e2b1b9c0Schristos  *
79e2b1b9c0Schristos  * Requires:
80e2b1b9c0Schristos  *
81e2b1b9c0Schristos  *	't' is a valid pointer.
82e2b1b9c0Schristos  *	nanoseconds < 1000000000.
83e2b1b9c0Schristos  */
84e2b1b9c0Schristos 
85f2e20987Schristos bool
86e2b1b9c0Schristos isc_interval_iszero(const isc_interval_t *i);
87e2b1b9c0Schristos /*
88f2e20987Schristos  * Returns true iff. 'i' is the zero interval.
89e2b1b9c0Schristos  *
90e2b1b9c0Schristos  * Requires:
91e2b1b9c0Schristos  *
92e2b1b9c0Schristos  *	'i' is a valid pointer.
93e2b1b9c0Schristos  */
94e2b1b9c0Schristos 
95e2b1b9c0Schristos /***
96e2b1b9c0Schristos  *** Absolute Times
97e2b1b9c0Schristos  ***/
98e2b1b9c0Schristos 
99e2b1b9c0Schristos /*
100e2b1b9c0Schristos  * The contents of this structure are private, and MUST NOT be accessed
101e2b1b9c0Schristos  * directly by callers.
102e2b1b9c0Schristos  *
103e2b1b9c0Schristos  * The contents are exposed only to allow callers to avoid dynamic allocation.
104e2b1b9c0Schristos  */
105e2b1b9c0Schristos 
106e2b1b9c0Schristos struct isc_time {
107e2b1b9c0Schristos 	FILETIME absolute;
108e2b1b9c0Schristos };
109e2b1b9c0Schristos 
110e2b1b9c0Schristos LIBISC_EXTERNAL_DATA extern const isc_time_t *const isc_time_epoch;
111e2b1b9c0Schristos 
112e2b1b9c0Schristos void
113e2b1b9c0Schristos isc_time_set(isc_time_t *t, unsigned int seconds, unsigned int nanoseconds);
114e2b1b9c0Schristos /*%<
115e2b1b9c0Schristos  * Set 't' to a value which represents the given number of seconds and
116e2b1b9c0Schristos  * nanoseconds since 00:00:00 January 1, 1970, UTC.
117e2b1b9c0Schristos  *
118e2b1b9c0Schristos  * Requires:
119e2b1b9c0Schristos  *\li   't' is a valid pointer.
120e2b1b9c0Schristos  *\li   nanoseconds < 1000000000.
121e2b1b9c0Schristos  */
122e2b1b9c0Schristos 
123e2b1b9c0Schristos void
124e2b1b9c0Schristos isc_time_settoepoch(isc_time_t *t);
125e2b1b9c0Schristos /*
126e2b1b9c0Schristos  * Set 't' to the time of the epoch.
127e2b1b9c0Schristos  *
128e2b1b9c0Schristos  * Notes:
129e2b1b9c0Schristos  * 	The date of the epoch is platform-dependent.
130e2b1b9c0Schristos  *
131e2b1b9c0Schristos  * Requires:
132e2b1b9c0Schristos  *
133e2b1b9c0Schristos  *	't' is a valid pointer.
134e2b1b9c0Schristos  */
135e2b1b9c0Schristos 
136f2e20987Schristos bool
137e2b1b9c0Schristos isc_time_isepoch(const isc_time_t *t);
138e2b1b9c0Schristos /*
139f2e20987Schristos  * Returns true iff. 't' is the epoch ("time zero").
140e2b1b9c0Schristos  *
141e2b1b9c0Schristos  * Requires:
142e2b1b9c0Schristos  *
143e2b1b9c0Schristos  *	't' is a valid pointer.
144e2b1b9c0Schristos  */
145e2b1b9c0Schristos 
146e2b1b9c0Schristos isc_result_t
147e2b1b9c0Schristos isc_time_now(isc_time_t *t);
148e2b1b9c0Schristos /*
149e2b1b9c0Schristos  * Set 't' to the current absolute time.
150e2b1b9c0Schristos  *
151e2b1b9c0Schristos  * Requires:
152e2b1b9c0Schristos  *
153e2b1b9c0Schristos  *	't' is a valid pointer.
154e2b1b9c0Schristos  *
155e2b1b9c0Schristos  * Returns:
156e2b1b9c0Schristos  *
157e2b1b9c0Schristos  *	Success
158e2b1b9c0Schristos  *	Unexpected error
159e2b1b9c0Schristos  *		Getting the time from the system failed.
160e2b1b9c0Schristos  *	Out of range
161e2b1b9c0Schristos  *		The time from the system is too large to be represented
162e2b1b9c0Schristos  *		in the current definition of isc_time_t.
163e2b1b9c0Schristos  */
164e2b1b9c0Schristos 
165e2b1b9c0Schristos isc_result_t
16676b1fd8fSchristos isc_time_now_hires(isc_time_t *t);
16776b1fd8fSchristos /*%<
16876b1fd8fSchristos  * Set 't' to the current absolute time. Uses higher resolution clocks
16976b1fd8fSchristos  * recommended when microsecond accuracy is required.
17076b1fd8fSchristos  *
17176b1fd8fSchristos  * Requires:
17276b1fd8fSchristos  *
17376b1fd8fSchristos  *\li	't' is a valid pointer.
17476b1fd8fSchristos  *
17576b1fd8fSchristos  * Returns:
17676b1fd8fSchristos  *
17776b1fd8fSchristos  *\li	Success
17876b1fd8fSchristos  *\li	Unexpected error
17976b1fd8fSchristos  *		Getting the time from the system failed.
18076b1fd8fSchristos  *\li	Out of range
18176b1fd8fSchristos  *		The time from the system is too large to be represented
18276b1fd8fSchristos  *		in the current definition of isc_time_t.
18376b1fd8fSchristos  */
18476b1fd8fSchristos 
18576b1fd8fSchristos isc_result_t
186e2b1b9c0Schristos isc_time_nowplusinterval(isc_time_t *t, const isc_interval_t *i);
187e2b1b9c0Schristos /*
188e2b1b9c0Schristos  * Set *t to the current absolute time + i.
189e2b1b9c0Schristos  *
190e2b1b9c0Schristos  * Note:
191e2b1b9c0Schristos  *	This call is equivalent to:
192e2b1b9c0Schristos  *
193e2b1b9c0Schristos  *		isc_time_now(t);
194e2b1b9c0Schristos  *		isc_time_add(t, i, t);
195e2b1b9c0Schristos  *
196e2b1b9c0Schristos  * Requires:
197e2b1b9c0Schristos  *
198e2b1b9c0Schristos  *	't' and 'i' are valid pointers.
199e2b1b9c0Schristos  *
200e2b1b9c0Schristos  * Returns:
201e2b1b9c0Schristos  *
202e2b1b9c0Schristos  *	Success
203e2b1b9c0Schristos  *	Unexpected error
204e2b1b9c0Schristos  *		Getting the time from the system failed.
205e2b1b9c0Schristos  *	Out of range
206e2b1b9c0Schristos  *		The interval added to the time from the system is too large to
207e2b1b9c0Schristos  *		be represented in the current definition of isc_time_t.
208e2b1b9c0Schristos  */
209e2b1b9c0Schristos 
210e2b1b9c0Schristos int
211e2b1b9c0Schristos isc_time_compare(const isc_time_t *t1, const isc_time_t *t2);
212e2b1b9c0Schristos /*
213e2b1b9c0Schristos  * Compare the times referenced by 't1' and 't2'
214e2b1b9c0Schristos  *
215e2b1b9c0Schristos  * Requires:
216e2b1b9c0Schristos  *
217e2b1b9c0Schristos  *	't1' and 't2' are valid pointers.
218e2b1b9c0Schristos  *
219e2b1b9c0Schristos  * Returns:
220e2b1b9c0Schristos  *
221e2b1b9c0Schristos  *	-1		t1 < t2		(comparing times, not pointers)
222e2b1b9c0Schristos  *	0		t1 = t2
223e2b1b9c0Schristos  *	1		t1 > t2
224e2b1b9c0Schristos  */
225e2b1b9c0Schristos 
226e2b1b9c0Schristos isc_result_t
227e2b1b9c0Schristos isc_time_add(const isc_time_t *t, const isc_interval_t *i, isc_time_t *result);
228e2b1b9c0Schristos /*
229e2b1b9c0Schristos  * Add 'i' to 't', storing the result in 'result'.
230e2b1b9c0Schristos  *
231e2b1b9c0Schristos  * Requires:
232e2b1b9c0Schristos  *
233e2b1b9c0Schristos  *	't', 'i', and 'result' are valid pointers.
234e2b1b9c0Schristos  *
235e2b1b9c0Schristos  * Returns:
236e2b1b9c0Schristos  * 	Success
237e2b1b9c0Schristos  *	Out of range
238e2b1b9c0Schristos  * 		The interval added to the time is too large to
239e2b1b9c0Schristos  *		be represented in the current definition of isc_time_t.
240e2b1b9c0Schristos  */
241e2b1b9c0Schristos 
242e2b1b9c0Schristos isc_result_t
243e2b1b9c0Schristos isc_time_subtract(const isc_time_t *t, const isc_interval_t *i,
244e2b1b9c0Schristos 		  isc_time_t *result);
245e2b1b9c0Schristos /*
246e2b1b9c0Schristos  * Subtract 'i' from 't', storing the result in 'result'.
247e2b1b9c0Schristos  *
248e2b1b9c0Schristos  * Requires:
249e2b1b9c0Schristos  *
250e2b1b9c0Schristos  *	't', 'i', and 'result' are valid pointers.
251e2b1b9c0Schristos  *
252e2b1b9c0Schristos  * Returns:
253e2b1b9c0Schristos  *	Success
254e2b1b9c0Schristos  *	Out of range
255e2b1b9c0Schristos  *		The interval is larger than the time since the epoch.
256e2b1b9c0Schristos  */
257e2b1b9c0Schristos 
258f2e20987Schristos uint64_t
259e2b1b9c0Schristos isc_time_microdiff(const isc_time_t *t1, const isc_time_t *t2);
260e2b1b9c0Schristos /*
261e2b1b9c0Schristos  * Find the difference in milliseconds between time t1 and time t2.
262e2b1b9c0Schristos  * t2 is the subtrahend of t1; ie, difference = t1 - t2.
263e2b1b9c0Schristos  *
264e2b1b9c0Schristos  * Requires:
265e2b1b9c0Schristos  *
266e2b1b9c0Schristos  *	't1' and 't2' are valid pointers.
267e2b1b9c0Schristos  *
268e2b1b9c0Schristos  * Returns:
269e2b1b9c0Schristos  *	The difference of t1 - t2, or 0 if t1 <= t2.
270e2b1b9c0Schristos  */
271e2b1b9c0Schristos 
272e2b1b9c0Schristos isc_result_t
273e2b1b9c0Schristos isc_time_parsehttptimestamp(char *input, isc_time_t *t);
274e2b1b9c0Schristos /*%<
275e2b1b9c0Schristos  * Parse the time in 'input' into the isc_time_t pointed to by 't',
276e2b1b9c0Schristos  * expecting a format like "Mon, 30 Aug 2000 04:06:47 GMT"
277e2b1b9c0Schristos  *
278e2b1b9c0Schristos  *  Requires:
279e2b1b9c0Schristos  *\li      'buf' and 't' are not NULL.
280e2b1b9c0Schristos  */
281e2b1b9c0Schristos 
282f2e20987Schristos uint32_t
283e2b1b9c0Schristos isc_time_nanoseconds(const isc_time_t *t);
284e2b1b9c0Schristos /*
285e2b1b9c0Schristos  * Return the number of nanoseconds stored in a time structure.
286e2b1b9c0Schristos  *
287e2b1b9c0Schristos  * Notes:
288e2b1b9c0Schristos  *	This is the number of nanoseconds in excess of the number
289e2b1b9c0Schristos  *	of seconds since the epoch; it will always be less than one
290e2b1b9c0Schristos  *	full second.
291e2b1b9c0Schristos  *
292e2b1b9c0Schristos  * Requires:
293e2b1b9c0Schristos  *	't' is a valid pointer.
294e2b1b9c0Schristos  *
295e2b1b9c0Schristos  * Ensures:
296e2b1b9c0Schristos  *	The returned value is less than 1*10^9.
297e2b1b9c0Schristos  */
298e2b1b9c0Schristos 
299e2b1b9c0Schristos void
300e2b1b9c0Schristos isc_time_formattimestamp(const isc_time_t *t, char *buf, unsigned int len);
301e2b1b9c0Schristos /*
302e2b1b9c0Schristos  * Format the time 't' into the buffer 'buf' of length 'len',
303e2b1b9c0Schristos  * using a format like "30-Aug-2000 04:06:47.997" and the local time zone.
304e2b1b9c0Schristos  * If the text does not fit in the buffer, the result is indeterminate,
305e2b1b9c0Schristos  * but is always guaranteed to be null terminated.
306e2b1b9c0Schristos  *
307e2b1b9c0Schristos  *  Requires:
308e2b1b9c0Schristos  *      'len' > 0
309e2b1b9c0Schristos  *      'buf' points to an array of at least len chars
310e2b1b9c0Schristos  *
311e2b1b9c0Schristos  */
312e2b1b9c0Schristos 
313e2b1b9c0Schristos void
314e2b1b9c0Schristos isc_time_formathttptimestamp(const isc_time_t *t, char *buf, unsigned int len);
315e2b1b9c0Schristos /*
316e2b1b9c0Schristos  * Format the time 't' into the buffer 'buf' of length 'len',
317e2b1b9c0Schristos  * using a format like "Mon, 30 Aug 2000 04:06:47 GMT"
318e2b1b9c0Schristos  * If the text does not fit in the buffer, the result is indeterminate,
319e2b1b9c0Schristos  * but is always guaranteed to be null terminated.
320e2b1b9c0Schristos  *
321e2b1b9c0Schristos  *  Requires:
322e2b1b9c0Schristos  *      'len' > 0
323e2b1b9c0Schristos  *      'buf' points to an array of at least len chars
324e2b1b9c0Schristos  *
325e2b1b9c0Schristos  */
326e2b1b9c0Schristos 
327e2b1b9c0Schristos isc_result_t
328e2b1b9c0Schristos isc_time_parsehttptimestamp(char *input, isc_time_t *t);
329e2b1b9c0Schristos /*%<
330e2b1b9c0Schristos  * Parse the time in 'input' into the isc_time_t pointed to by 't',
331e2b1b9c0Schristos  * expecting a format like "Mon, 30 Aug 2000 04:06:47 GMT"
332e2b1b9c0Schristos  *
333e2b1b9c0Schristos  *  Requires:
334e2b1b9c0Schristos  *\li      'buf' and 't' are not NULL.
335e2b1b9c0Schristos  */
336e2b1b9c0Schristos 
337e2b1b9c0Schristos void
338e2b1b9c0Schristos isc_time_formatISO8601L(const isc_time_t *t, char *buf, unsigned int len);
339e2b1b9c0Schristos /*%<
340e2b1b9c0Schristos  * Format the time 't' into the buffer 'buf' of length 'len',
341e2b1b9c0Schristos  * using the ISO8601 format: "yyyy-mm-ddThh:mm:ss"
342e2b1b9c0Schristos  * If the text does not fit in the buffer, the result is indeterminate,
343e2b1b9c0Schristos  * but is always guaranteed to be null terminated.
344e2b1b9c0Schristos  *
345e2b1b9c0Schristos  *  Requires:
346e2b1b9c0Schristos  *\li      'len' > 0
347e2b1b9c0Schristos  *\li      'buf' points to an array of at least len chars
348e2b1b9c0Schristos  *
349e2b1b9c0Schristos  */
350e2b1b9c0Schristos 
351e2b1b9c0Schristos void
352e2b1b9c0Schristos isc_time_formatISO8601Lms(const isc_time_t *t, char *buf, unsigned int len);
353e2b1b9c0Schristos /*%<
354e2b1b9c0Schristos  * Format the time 't' into the buffer 'buf' of length 'len',
355e2b1b9c0Schristos  * using the ISO8601 format: "yyyy-mm-ddThh:mm:ss.sss"
356e2b1b9c0Schristos  * If the text does not fit in the buffer, the result is indeterminate,
357e2b1b9c0Schristos  * but is always guaranteed to be null terminated.
358e2b1b9c0Schristos  *
359e2b1b9c0Schristos  *  Requires:
360e2b1b9c0Schristos  *\li      'len' > 0
361e2b1b9c0Schristos  *\li      'buf' points to an array of at least len chars
362e2b1b9c0Schristos  *
363e2b1b9c0Schristos  */
364e2b1b9c0Schristos 
365e2b1b9c0Schristos void
36673584a28Schristos isc_time_formatISO8601Lus(const isc_time_t *t, char *buf, unsigned int len);
36773584a28Schristos /*%<
36873584a28Schristos  * Format the time 't' into the buffer 'buf' of length 'len',
36973584a28Schristos  * using the ISO8601 format: "yyyy-mm-ddThh:mm:ss.ssssss"
37073584a28Schristos  * If the text does not fit in the buffer, the result is indeterminate,
37173584a28Schristos  * but is always guaranteed to be null terminated.
37273584a28Schristos  *
37373584a28Schristos  *  Requires:
37473584a28Schristos  *\li      'len' > 0
37573584a28Schristos  *\li      'buf' points to an array of at least len chars
37673584a28Schristos  *
37773584a28Schristos  */
37873584a28Schristos 
37973584a28Schristos void
380e2b1b9c0Schristos isc_time_formatISO8601(const isc_time_t *t, char *buf, unsigned int len);
381e2b1b9c0Schristos /*%<
382e2b1b9c0Schristos  * Format the time 't' into the buffer 'buf' of length 'len',
383e2b1b9c0Schristos  * using the ISO8601 format: "yyyy-mm-ddThh:mm:ssZ"
384e2b1b9c0Schristos  * If the text does not fit in the buffer, the result is indeterminate,
385e2b1b9c0Schristos  * but is always guaranteed to be null terminated.
386e2b1b9c0Schristos  *
387e2b1b9c0Schristos  *  Requires:
388e2b1b9c0Schristos  *\li      'len' > 0
389e2b1b9c0Schristos  *\li      'buf' points to an array of at least len chars
390e2b1b9c0Schristos  *
391e2b1b9c0Schristos  */
392e2b1b9c0Schristos 
393e2b1b9c0Schristos void
394e2b1b9c0Schristos isc_time_formatISO8601ms(const isc_time_t *t, char *buf, unsigned int len);
395e2b1b9c0Schristos /*%<
396e2b1b9c0Schristos  * Format the time 't' into the buffer 'buf' of length 'len',
397e2b1b9c0Schristos  * using the ISO8601 format: "yyyy-mm-ddThh:mm:ss.sssZ"
398e2b1b9c0Schristos  * If the text does not fit in the buffer, the result is indeterminate,
399e2b1b9c0Schristos  * but is always guaranteed to be null terminated.
400e2b1b9c0Schristos  *
401e2b1b9c0Schristos  *  Requires:
402e2b1b9c0Schristos  *\li      'len' > 0
403e2b1b9c0Schristos  *\li      'buf' points to an array of at least len chars
404e2b1b9c0Schristos  *
405e2b1b9c0Schristos  */
406e2b1b9c0Schristos 
407e2b1b9c0Schristos void
40873584a28Schristos isc_time_formatISO8601us(const isc_time_t *t, char *buf, unsigned int len);
40973584a28Schristos /*%<
41073584a28Schristos  * Format the time 't' into the buffer 'buf' of length 'len',
41173584a28Schristos  * using the ISO8601 format: "yyyy-mm-ddThh:mm:ss.ssssssZ"
41273584a28Schristos  * If the text does not fit in the buffer, the result is indeterminate,
41373584a28Schristos  * but is always guaranteed to be null terminated.
41473584a28Schristos  *
41573584a28Schristos  *  Requires:
41673584a28Schristos  *\li      'len' > 0
41773584a28Schristos  *\li      'buf' points to an array of at least len chars
41873584a28Schristos  *
41973584a28Schristos  */
42073584a28Schristos 
42173584a28Schristos void
422e2b1b9c0Schristos isc_time_formatshorttimestamp(const isc_time_t *t, char *buf, unsigned int len);
423e2b1b9c0Schristos /*%<
424e2b1b9c0Schristos  * Format the time 't' into the buffer 'buf' of length 'len',
4259742fdb4Schristos  * using the format "yyyymmddhhmmsssss" useful for file timestamping.
426e2b1b9c0Schristos  * If the text does not fit in the buffer, the result is indeterminate,
427e2b1b9c0Schristos  * but is always guaranteed to be null terminated.
428e2b1b9c0Schristos  *
429e2b1b9c0Schristos  *  Requires:
430e2b1b9c0Schristos  *\li      'len' > 0
431e2b1b9c0Schristos  *\li      'buf' points to an array of at least len chars
432e2b1b9c0Schristos  *
433e2b1b9c0Schristos  */
434e2b1b9c0Schristos 
435f2e20987Schristos uint32_t
436e2b1b9c0Schristos isc_time_seconds(const isc_time_t *t);
437e2b1b9c0Schristos /*%<
438e2b1b9c0Schristos  * Return the number of seconds since the epoch stored in a time structure.
439e2b1b9c0Schristos  *
440e2b1b9c0Schristos  * Requires:
441e2b1b9c0Schristos  *
442e2b1b9c0Schristos  *\li	't' is a valid pointer.
443e2b1b9c0Schristos  */
444e2b1b9c0Schristos 
445e2b1b9c0Schristos isc_result_t
446e2b1b9c0Schristos isc_time_secondsastimet(const isc_time_t *t, time_t *secondsp);
447e2b1b9c0Schristos /*%<
448e2b1b9c0Schristos  * Ensure the number of seconds in an isc_time_t is representable by a time_t.
449e2b1b9c0Schristos  *
450e2b1b9c0Schristos  * Notes:
451e2b1b9c0Schristos  *\li	The number of seconds stored in an isc_time_t might be larger
452e2b1b9c0Schristos  *	than the number of seconds a time_t is able to handle.  Since
453e2b1b9c0Schristos  *	time_t is mostly opaque according to the ANSI/ISO standard
454e2b1b9c0Schristos  *	(essentially, all you can be sure of is that it is an arithmetic type,
455e2b1b9c0Schristos  *	not even necessarily integral), it can be tricky to ensure that
456e2b1b9c0Schristos  *	the isc_time_t is in the range a time_t can handle.  Use this
457e2b1b9c0Schristos  *	function in place of isc_time_seconds() any time you need to set a
458e2b1b9c0Schristos  *	time_t from an isc_time_t.
459e2b1b9c0Schristos  *
460e2b1b9c0Schristos  * Requires:
461e2b1b9c0Schristos  *\li	't' is a valid pointer.
462e2b1b9c0Schristos  *
463e2b1b9c0Schristos  * Returns:
464e2b1b9c0Schristos  *\li	Success
465e2b1b9c0Schristos  *\li	Out of range
466e2b1b9c0Schristos  */
467e2b1b9c0Schristos 
468e2b1b9c0Schristos ISC_LANG_ENDDECLS
469e2b1b9c0Schristos 
470e2b1b9c0Schristos #endif /* ISC_TIME_H */
471