1 /*	$NetBSD: time.h,v 1.7 2015/07/08 17:29:00 christos Exp $	*/
2 
3 /*
4  * Copyright (C) 2004-2009, 2012, 2014, 2015  Internet Systems Consortium, Inc. ("ISC")
5  * Copyright (C) 1998-2001  Internet Software Consortium.
6  *
7  * Permission to use, copy, modify, and/or distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17  * PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 /* Id: time.h,v 1.40 2009/01/05 23:47:54 tbox Exp  */
21 
22 #ifndef ISC_TIME_H
23 #define ISC_TIME_H 1
24 
25 /*! \file */
26 
27 #include <isc/lang.h>
28 #include <isc/types.h>
29 
30 /***
31  *** Intervals
32  ***/
33 
34 /*!
35  *  \brief
36  * The contents of this structure are private, and MUST NOT be accessed
37  * directly by callers.
38  *
39  * The contents are exposed only to allow callers to avoid dynamic allocation.
40  */
41 struct isc_interval {
42 	unsigned int seconds;
43 	unsigned int nanoseconds;
44 };
45 
46 extern const isc_interval_t * const isc_interval_zero;
47 
48 /*
49  * ISC_FORMATHTTPTIMESTAMP_SIZE needs to be 30 in C locale and potentially
50  * more for other locales to handle longer national abbreviations when
51  * expanding strftime's %a and %b.
52  */
53 #define ISC_FORMATHTTPTIMESTAMP_SIZE 50
54 
55 ISC_LANG_BEGINDECLS
56 
57 void
58 isc_interval_set(isc_interval_t *i,
59 		 unsigned int seconds, unsigned int nanoseconds);
60 /*%<
61  * Set 'i' to a value representing an interval of 'seconds' seconds and
62  * 'nanoseconds' nanoseconds, suitable for use in isc_time_add() and
63  * isc_time_subtract().
64  *
65  * Requires:
66  *
67  *\li	't' is a valid pointer.
68  *\li	nanoseconds < 1000000000.
69  */
70 
71 isc_boolean_t
72 isc_interval_iszero(const isc_interval_t *i);
73 /*%<
74  * Returns ISC_TRUE iff. 'i' is the zero interval.
75  *
76  * Requires:
77  *
78  *\li	'i' is a valid pointer.
79  */
80 
81 /***
82  *** Absolute Times
83  ***/
84 
85 /*%
86  * The contents of this structure are private, and MUST NOT be accessed
87  * directly by callers.
88  *
89  * The contents are exposed only to allow callers to avoid dynamic allocation.
90  */
91 
92 struct isc_time {
93 	unsigned int	seconds;
94 	unsigned int	nanoseconds;
95 };
96 
97 extern const isc_time_t * const isc_time_epoch;
98 
99 void
100 isc_time_set(isc_time_t *t, unsigned int seconds, unsigned int nanoseconds);
101 /*%<
102  * Set 't' to a value which represents the given number of seconds and
103  * nanoseconds since 00:00:00 January 1, 1970, UTC.
104  *
105  * Notes:
106  *\li	The Unix version of this call is equivalent to:
107  *\code
108  *	isc_time_settoepoch(t);
109  *	isc_interval_set(i, seconds, nanoseconds);
110  *	isc_time_add(t, i, t);
111  *\endcode
112  *
113  * Requires:
114  *\li	't' is a valid pointer.
115  *\li	nanoseconds < 1000000000.
116  */
117 
118 void
119 isc_time_settoepoch(isc_time_t *t);
120 /*%<
121  * Set 't' to the time of the epoch.
122  *
123  * Notes:
124  *\li	The date of the epoch is platform-dependent.
125  *
126  * Requires:
127  *
128  *\li	't' is a valid pointer.
129  */
130 
131 isc_boolean_t
132 isc_time_isepoch(const isc_time_t *t);
133 /*%<
134  * Returns ISC_TRUE iff. 't' is the epoch ("time zero").
135  *
136  * Requires:
137  *
138  *\li	't' is a valid pointer.
139  */
140 
141 isc_result_t
142 isc_time_now(isc_time_t *t);
143 /*%<
144  * Set 't' to the current absolute time.
145  *
146  * Requires:
147  *
148  *\li	't' is a valid pointer.
149  *
150  * Returns:
151  *
152  *\li	Success
153  *\li	Unexpected error
154  *		Getting the time from the system failed.
155  *\li	Out of range
156  *		The time from the system is too large to be represented
157  *		in the current definition of isc_time_t.
158  */
159 
160 isc_result_t
161 isc_time_nowplusinterval(isc_time_t *t, const isc_interval_t *i);
162 /*%<
163  * Set *t to the current absolute time + i.
164  *
165  * Note:
166  *\li	This call is equivalent to:
167  *
168  *\code
169  *		isc_time_now(t);
170  *		isc_time_add(t, i, t);
171  *\endcode
172  *
173  * Requires:
174  *
175  *\li	't' and 'i' are valid pointers.
176  *
177  * Returns:
178  *
179  *\li	Success
180  *\li	Unexpected error
181  *		Getting the time from the system failed.
182  *\li	Out of range
183  *		The interval added to the time from the system is too large to
184  *		be represented in the current definition of isc_time_t.
185  */
186 
187 int
188 isc_time_compare(const isc_time_t *t1, const isc_time_t *t2);
189 /*%<
190  * Compare the times referenced by 't1' and 't2'
191  *
192  * Requires:
193  *
194  *\li	't1' and 't2' are valid pointers.
195  *
196  * Returns:
197  *
198  *\li	-1		t1 < t2		(comparing times, not pointers)
199  *\li	0		t1 = t2
200  *\li	1		t1 > t2
201  */
202 
203 isc_result_t
204 isc_time_add(const isc_time_t *t, const isc_interval_t *i, isc_time_t *result);
205 /*%<
206  * Add 'i' to 't', storing the result in 'result'.
207  *
208  * Requires:
209  *
210  *\li	't', 'i', and 'result' are valid pointers.
211  *
212  * Returns:
213  *\li	Success
214  *\li	Out of range
215  * 		The interval added to the time is too large to
216  *		be represented in the current definition of isc_time_t.
217  */
218 
219 isc_result_t
220 isc_time_subtract(const isc_time_t *t, const isc_interval_t *i,
221 		  isc_time_t *result);
222 /*%<
223  * Subtract 'i' from '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 is larger than the time since the epoch.
233  */
234 
235 isc_uint64_t
236 isc_time_microdiff(const isc_time_t *t1, const isc_time_t *t2);
237 /*%<
238  * Find the difference in microseconds between time t1 and time t2.
239  * t2 is the subtrahend of t1; ie, difference = t1 - t2.
240  *
241  * Requires:
242  *
243  *\li	't1' and 't2' are valid pointers.
244  *
245  * Returns:
246  *\li	The difference of t1 - t2, or 0 if t1 <= t2.
247  */
248 
249 isc_uint32_t
250 isc_time_seconds(const isc_time_t *t);
251 /*%<
252  * Return the number of seconds since the epoch stored in a time structure.
253  *
254  * Requires:
255  *
256  *\li	't' is a valid pointer.
257  */
258 
259 isc_result_t
260 isc_time_secondsastimet(const isc_time_t *t, time_t *secondsp);
261 /*%<
262  * Ensure the number of seconds in an isc_time_t is representable by a time_t.
263  *
264  * Notes:
265  *\li	The number of seconds stored in an isc_time_t might be larger
266  *	than the number of seconds a time_t is able to handle.  Since
267  *	time_t is mostly opaque according to the ANSI/ISO standard
268  *	(essentially, all you can be sure of is that it is an arithmetic type,
269  *	not even necessarily integral), it can be tricky to ensure that
270  *	the isc_time_t is in the range a time_t can handle.  Use this
271  *	function in place of isc_time_seconds() any time you need to set a
272  *	time_t from an isc_time_t.
273  *
274  * Requires:
275  *\li	't' is a valid pointer.
276  *
277  * Returns:
278  *\li	Success
279  *\li	Out of range
280  */
281 
282 isc_uint32_t
283 isc_time_nanoseconds(const isc_time_t *t);
284 /*%<
285  * Return the number of nanoseconds stored in a time structure.
286  *
287  * Notes:
288  *\li	This is the number of nanoseconds in excess of the number
289  *	of seconds since the epoch; it will always be less than one
290  *	full second.
291  *
292  * Requires:
293  *\li	't' is a valid pointer.
294  *
295  * Ensures:
296  *\li	The returned value is less than 1*10^9.
297  */
298 
299 void
300 isc_time_formattimestamp(const isc_time_t *t, char *buf, unsigned int len);
301 /*%<
302  * Format the time 't' into the buffer 'buf' of length 'len',
303  * using a format like "30-Aug-2000 04:06:47.997" and the local time zone.
304  * If the text does not fit in the buffer, the result is indeterminate,
305  * but is always guaranteed to be null terminated.
306  *
307  *  Requires:
308  *\li      'len' > 0
309  *\li      'buf' points to an array of at least len chars
310  *
311  */
312 
313 void
314 isc_time_formathttptimestamp(const isc_time_t *t, char *buf, unsigned int len);
315 /*%<
316  * Format the time 't' into the buffer 'buf' of length 'len',
317  * using a format like "Mon, 30 Aug 2000 04:06:47 GMT"
318  * If the text does not fit in the buffer, the result is indeterminate,
319  * but is always guaranteed to be null terminated.
320  *
321  *  Requires:
322  *\li      'len' > 0
323  *\li      'buf' points to an array of at least len chars
324  *
325  */
326 
327 isc_result_t
328 isc_time_parsehttptimestamp(char *input, isc_time_t *t);
329 /*%<
330  * Parse the time in 'input' into the isc_time_t pointed to by 't',
331  * expecting a format like "Mon, 30 Aug 2000 04:06:47 GMT"
332  *
333  *  Requires:
334  *\li      'buf' and 't' are not NULL.
335  */
336 
337 void
338 isc_time_formatISO8601(const isc_time_t *t, char *buf, unsigned int len);
339 /*%<
340  * Format the time 't' into the buffer 'buf' of length 'len',
341  * using the ISO8601 format: "yyyy-mm-ddThh:mm:ssZ"
342  * If the text does not fit in the buffer, the result is indeterminate,
343  * but is always guaranteed to be null terminated.
344  *
345  *  Requires:
346  *\li      'len' > 0
347  *\li      'buf' points to an array of at least len chars
348  *
349  */
350 
351 ISC_LANG_ENDDECLS
352 
353 #endif /* ISC_TIME_H */
354