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