xref: /netbsd-src/external/mpl/dhcp/bind/dist/lib/isc/unix/include/isc/time.h (revision 4afad4b7fa6d4a0d3dedf41d1587a7250710ae54)
1 /*	$NetBSD: time.h,v 1.1 2024/02/18 20:57:58 christos Exp $	*/
2 
3 /*
4  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
5  *
6  * SPDX-License-Identifier: MPL-2.0
7  *
8  * This Source Code Form is subject to the terms of the Mozilla Public
9  * License, v. 2.0. If a copy of the MPL was not distributed with this
10  * file, you can obtain one at https://mozilla.org/MPL/2.0/.
11  *
12  * See the COPYRIGHT file distributed with this work for additional
13  * information regarding copyright ownership.
14  */
15 
16 #ifndef ISC_TIME_H
17 #define ISC_TIME_H 1
18 
19 /*! \file */
20 
21 #include <inttypes.h>
22 #include <stdbool.h>
23 
24 #include <isc/lang.h>
25 #include <isc/types.h>
26 
27 /***
28  *** Intervals
29  ***/
30 
31 /*!
32  *  \brief
33  * The contents of this structure are private, and MUST NOT be accessed
34  * directly by callers.
35  *
36  * The contents are exposed only to allow callers to avoid dynamic allocation.
37  */
38 struct isc_interval {
39 	unsigned int seconds;
40 	unsigned int nanoseconds;
41 };
42 
43 extern const isc_interval_t *const isc_interval_zero;
44 
45 /*
46  * ISC_FORMATHTTPTIMESTAMP_SIZE needs to be 30 in C locale and potentially
47  * more for other locales to handle longer national abbreviations when
48  * expanding strftime's %a and %b.
49  */
50 #define ISC_FORMATHTTPTIMESTAMP_SIZE 50
51 
52 ISC_LANG_BEGINDECLS
53 
54 void
55 isc_interval_set(isc_interval_t *i, unsigned int seconds,
56 		 unsigned int nanoseconds);
57 /*%<
58  * Set 'i' to a value representing an interval of 'seconds' seconds and
59  * 'nanoseconds' nanoseconds, suitable for use in isc_time_add() and
60  * isc_time_subtract().
61  *
62  * Requires:
63  *
64  *\li	't' is a valid pointer.
65  *\li	nanoseconds < 1000000000.
66  */
67 
68 bool
69 isc_interval_iszero(const isc_interval_t *i);
70 /*%<
71  * Returns true iff. 'i' is the zero interval.
72  *
73  * Requires:
74  *
75  *\li	'i' is a valid pointer.
76  */
77 
78 /***
79  *** Absolute Times
80  ***/
81 
82 /*%
83  * The contents of this structure are private, and MUST NOT be accessed
84  * directly by callers.
85  *
86  * The contents are exposed only to allow callers to avoid dynamic allocation.
87  */
88 
89 struct isc_time {
90 	unsigned int seconds;
91 	unsigned int nanoseconds;
92 };
93 
94 extern const isc_time_t *const isc_time_epoch;
95 
96 void
97 isc_time_set(isc_time_t *t, unsigned int seconds, unsigned int nanoseconds);
98 /*%<
99  * Set 't' to a value which represents the given number of seconds and
100  * nanoseconds since 00:00:00 January 1, 1970, UTC.
101  *
102  * Notes:
103  *\li	The Unix version of this call is equivalent to:
104  *\code
105  *	isc_time_settoepoch(t);
106  *	isc_interval_set(i, seconds, nanoseconds);
107  *	isc_time_add(t, i, t);
108  *\endcode
109  *
110  * Requires:
111  *\li	't' is a valid pointer.
112  *\li	nanoseconds < 1000000000.
113  */
114 
115 void
116 isc_time_settoepoch(isc_time_t *t);
117 /*%<
118  * Set 't' to the time of the epoch.
119  *
120  * Notes:
121  *\li	The date of the epoch is platform-dependent.
122  *
123  * Requires:
124  *
125  *\li	't' is a valid pointer.
126  */
127 
128 bool
129 isc_time_isepoch(const isc_time_t *t);
130 /*%<
131  * Returns true iff. 't' is the epoch ("time zero").
132  *
133  * Requires:
134  *
135  *\li	't' is a valid pointer.
136  */
137 
138 isc_result_t
139 isc_time_now(isc_time_t *t);
140 /*%<
141  * Set 't' to the current absolute time.
142  *
143  * Requires:
144  *
145  *\li	't' is a valid pointer.
146  *
147  * Returns:
148  *
149  *\li	Success
150  *\li	Unexpected error
151  *		Getting the time from the system failed.
152  *\li	Out of range
153  *		The time from the system is too large to be represented
154  *		in the current definition of isc_time_t.
155  */
156 
157 isc_result_t
158 isc_time_now_hires(isc_time_t *t);
159 /*%<
160  * Set 't' to the current absolute time. Uses higher resolution clocks
161  * recommended when microsecond accuracy is required.
162  *
163  * Requires:
164  *
165  *\li	't' is a valid pointer.
166  *
167  * Returns:
168  *
169  *\li	Success
170  *\li	Unexpected error
171  *		Getting the time from the system failed.
172  *\li	Out of range
173  *		The time from the system is too large to be represented
174  *		in the current definition of isc_time_t.
175  */
176 
177 isc_result_t
178 isc_time_nowplusinterval(isc_time_t *t, const isc_interval_t *i);
179 /*%<
180  * Set *t to the current absolute time + i.
181  *
182  * Note:
183  *\li	This call is equivalent to:
184  *
185  *\code
186  *		isc_time_now(t);
187  *		isc_time_add(t, i, t);
188  *\endcode
189  *
190  * Requires:
191  *
192  *\li	't' and 'i' are valid pointers.
193  *
194  * Returns:
195  *
196  *\li	Success
197  *\li	Unexpected error
198  *		Getting the time from the system failed.
199  *\li	Out of range
200  *		The interval added to the time from the system is too large to
201  *		be represented in the current definition of isc_time_t.
202  */
203 
204 int
205 isc_time_compare(const isc_time_t *t1, const isc_time_t *t2);
206 /*%<
207  * Compare the times referenced by 't1' and 't2'
208  *
209  * Requires:
210  *
211  *\li	't1' and 't2' are valid pointers.
212  *
213  * Returns:
214  *
215  *\li	-1		t1 < t2		(comparing times, not pointers)
216  *\li	0		t1 = t2
217  *\li	1		t1 > t2
218  */
219 
220 isc_result_t
221 isc_time_add(const isc_time_t *t, const isc_interval_t *i, isc_time_t *result);
222 /*%<
223  * Add 'i' to 't', storing the result in 'result'.
224  *
225  * Requires:
226  *
227  *\li	't', 'i', and 'result' are valid pointers.
228  *
229  * Returns:
230  *\li	Success
231  *\li	Out of range
232  * 		The interval added to the time is too large to
233  *		be represented in the current definition of isc_time_t.
234  */
235 
236 isc_result_t
237 isc_time_subtract(const isc_time_t *t, const isc_interval_t *i,
238 		  isc_time_t *result);
239 /*%<
240  * Subtract 'i' from 't', storing the result in 'result'.
241  *
242  * Requires:
243  *
244  *\li	't', 'i', and 'result' are valid pointers.
245  *
246  * Returns:
247  *\li	Success
248  *\li	Out of range
249  *		The interval is larger than the time since the epoch.
250  */
251 
252 uint64_t
253 isc_time_microdiff(const isc_time_t *t1, const isc_time_t *t2);
254 /*%<
255  * Find the difference in microseconds between time t1 and time t2.
256  * t2 is the subtrahend of t1; ie, difference = t1 - t2.
257  *
258  * Requires:
259  *
260  *\li	't1' and 't2' are valid pointers.
261  *
262  * Returns:
263  *\li	The difference of t1 - t2, or 0 if t1 <= t2.
264  */
265 
266 uint32_t
267 isc_time_seconds(const isc_time_t *t);
268 /*%<
269  * Return the number of seconds since the epoch stored in a time structure.
270  *
271  * Requires:
272  *
273  *\li	't' is a valid pointer.
274  */
275 
276 isc_result_t
277 isc_time_secondsastimet(const isc_time_t *t, time_t *secondsp);
278 /*%<
279  * Ensure the number of seconds in an isc_time_t is representable by a time_t.
280  *
281  * Notes:
282  *\li	The number of seconds stored in an isc_time_t might be larger
283  *	than the number of seconds a time_t is able to handle.  Since
284  *	time_t is mostly opaque according to the ANSI/ISO standard
285  *	(essentially, all you can be sure of is that it is an arithmetic type,
286  *	not even necessarily integral), it can be tricky to ensure that
287  *	the isc_time_t is in the range a time_t can handle.  Use this
288  *	function in place of isc_time_seconds() any time you need to set a
289  *	time_t from an isc_time_t.
290  *
291  * Requires:
292  *\li	't' is a valid pointer.
293  *
294  * Returns:
295  *\li	Success
296  *\li	Out of range
297  */
298 
299 uint32_t
300 isc_time_nanoseconds(const isc_time_t *t);
301 /*%<
302  * Return the number of nanoseconds stored in a time structure.
303  *
304  * Notes:
305  *\li	This is the number of nanoseconds in excess of the number
306  *	of seconds since the epoch; it will always be less than one
307  *	full second.
308  *
309  * Requires:
310  *\li	't' is a valid pointer.
311  *
312  * Ensures:
313  *\li	The returned value is less than 1*10^9.
314  */
315 
316 void
317 isc_time_formattimestamp(const isc_time_t *t, char *buf, unsigned int len);
318 /*%<
319  * Format the time 't' into the buffer 'buf' of length 'len',
320  * using a format like "30-Aug-2000 04:06:47.997" and the local time zone.
321  * If the text does not fit in the buffer, the result is indeterminate,
322  * but is always guaranteed to be null terminated.
323  *
324  *  Requires:
325  *\li      'len' > 0
326  *\li      'buf' points to an array of at least len chars
327  *
328  */
329 
330 void
331 isc_time_formathttptimestamp(const isc_time_t *t, char *buf, unsigned int len);
332 /*%<
333  * Format the time 't' into the buffer 'buf' of length 'len',
334  * using a format like "Mon, 30 Aug 2000 04:06:47 GMT"
335  * If the text does not fit in the buffer, the result is indeterminate,
336  * but is always guaranteed to be null terminated.
337  *
338  *  Requires:
339  *\li      'len' > 0
340  *\li      'buf' points to an array of at least len chars
341  *
342  */
343 
344 isc_result_t
345 isc_time_parsehttptimestamp(char *input, isc_time_t *t);
346 /*%<
347  * Parse the time in 'input' into the isc_time_t pointed to by 't',
348  * expecting a format like "Mon, 30 Aug 2000 04:06:47 GMT"
349  *
350  *  Requires:
351  *\li      'buf' and 't' are not NULL.
352  */
353 
354 void
355 isc_time_formatISO8601L(const isc_time_t *t, char *buf, unsigned int len);
356 /*%<
357  * Format the time 't' into the buffer 'buf' of length 'len',
358  * using the ISO8601 format: "yyyy-mm-ddThh:mm:ss"
359  * If the text does not fit in the buffer, the result is indeterminate,
360  * but is always guaranteed to be null terminated.
361  *
362  *  Requires:
363  *\li      'len' > 0
364  *\li      'buf' points to an array of at least len chars
365  *
366  */
367 
368 void
369 isc_time_formatISO8601Lms(const isc_time_t *t, char *buf, unsigned int len);
370 /*%<
371  * Format the time 't' into the buffer 'buf' of length 'len',
372  * using the ISO8601 format: "yyyy-mm-ddThh:mm:ss.sss"
373  * If the text does not fit in the buffer, the result is indeterminate,
374  * but is always guaranteed to be null terminated.
375  *
376  *  Requires:
377  *\li      'len' > 0
378  *\li      'buf' points to an array of at least len chars
379  *
380  */
381 
382 void
383 isc_time_formatISO8601Lus(const isc_time_t *t, char *buf, unsigned int len);
384 /*%<
385  * Format the time 't' into the buffer 'buf' of length 'len',
386  * using the ISO8601 format: "yyyy-mm-ddThh:mm:ss.ssssss"
387  * If the text does not fit in the buffer, the result is indeterminate,
388  * but is always guaranteed to be null terminated.
389  *
390  *  Requires:
391  *\li      'len' > 0
392  *\li      'buf' points to an array of at least len chars
393  *
394  */
395 
396 void
397 isc_time_formatISO8601(const isc_time_t *t, char *buf, unsigned int len);
398 /*%<
399  * Format the time 't' into the buffer 'buf' of length 'len',
400  * using the ISO8601 format: "yyyy-mm-ddThh:mm:ssZ"
401  * If the text does not fit in the buffer, the result is indeterminate,
402  * but is always guaranteed to be null terminated.
403  *
404  *  Requires:
405  *\li      'len' > 0
406  *\li      'buf' points to an array of at least len chars
407  *
408  */
409 
410 void
411 isc_time_formatISO8601ms(const isc_time_t *t, char *buf, unsigned int len);
412 /*%<
413  * Format the time 't' into the buffer 'buf' of length 'len',
414  * using the ISO8601 format: "yyyy-mm-ddThh:mm:ss.sssZ"
415  * If the text does not fit in the buffer, the result is indeterminate,
416  * but is always guaranteed to be null terminated.
417  *
418  *  Requires:
419  *\li      'len' > 0
420  *\li      'buf' points to an array of at least len chars
421  *
422  */
423 
424 void
425 isc_time_formatISO8601us(const isc_time_t *t, char *buf, unsigned int len);
426 /*%<
427  * Format the time 't' into the buffer 'buf' of length 'len',
428  * using the ISO8601 format: "yyyy-mm-ddThh:mm:ss.ssssssZ"
429  * If the text does not fit in the buffer, the result is indeterminate,
430  * but is always guaranteed to be null terminated.
431  *
432  *  Requires:
433  *\li      'len' > 0
434  *\li      'buf' points to an array of at least len chars
435  *
436  */
437 
438 void
439 isc_time_formatshorttimestamp(const isc_time_t *t, char *buf, unsigned int len);
440 /*%<
441  * Format the time 't' into the buffer 'buf' of length 'len',
442  * using the format "yyyymmddhhmmsssss" useful for file timestamping.
443  * If the text does not fit in the buffer, the result is indeterminate,
444  * but is always guaranteed to be null terminated.
445  *
446  *  Requires:
447  *\li      'len' > 0
448  *\li      'buf' points to an array of at least len chars
449  *
450  */
451 
452 ISC_LANG_ENDDECLS
453 
454 #endif /* ISC_TIME_H */
455