Sync usage with man page.
[netbsd-mini2440.git] / external / bsd / ntp / dist / lib / isc / win32 / time.c
blob557e4d314da537b6c591cdeb85fa0764c8d82028
1 /* $NetBSD$ */
3 /*
4 * Copyright (C) 2004, 2006-2008 Internet Systems Consortium, Inc. ("ISC")
5 * Copyright (C) 1998-2001, 2003 Internet Software Consortium.
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.
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.
20 /* Id: time.c,v 1.48 2008/09/08 23:47:10 tbox Exp */
22 #include <config.h>
24 #include <errno.h>
25 #include <limits.h>
26 #include <stddef.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <time.h>
31 #include <windows.h>
33 #include <isc/assertions.h>
34 #include <isc/time.h>
35 #include <isc/util.h>
38 * struct FILETIME uses "100-nanoseconds intervals".
39 * NS / S = 1000000000 (10^9).
40 * While it is reasonably obvious that this makes the needed
41 * conversion factor 10^7, it is coded this way for additional clarity.
43 #define NS_PER_S 1000000000
44 #define NS_INTERVAL 100
45 #define INTERVALS_PER_S (NS_PER_S / NS_INTERVAL)
46 #define UINT64_MAX _UI64_MAX
48 /***
49 *** Absolute Times
50 ***/
52 static isc_time_t epoch = { { 0, 0 } };
53 LIBISC_EXTERNAL_DATA isc_time_t *isc_time_epoch = &epoch;
55 /***
56 *** Intervals
57 ***/
59 static isc_interval_t zero_interval = { 0 };
60 LIBISC_EXTERNAL_DATA isc_interval_t *isc_interval_zero = &zero_interval;
62 void
63 isc_interval_set(isc_interval_t *i, unsigned int seconds,
64 unsigned int nanoseconds)
66 REQUIRE(i != NULL);
67 REQUIRE(nanoseconds < NS_PER_S);
70 * This rounds nanoseconds up not down.
72 i->interval = (LONGLONG)seconds * INTERVALS_PER_S
73 + (nanoseconds + NS_INTERVAL - 1) / NS_INTERVAL;
76 isc_boolean_t
77 isc_interval_iszero(const isc_interval_t *i) {
78 REQUIRE(i != NULL);
79 if (i->interval == 0)
80 return (ISC_TRUE);
82 return (ISC_FALSE);
85 void
86 isc_time_set(isc_time_t *t, unsigned int seconds, unsigned int nanoseconds) {
87 SYSTEMTIME epoch = { 1970, 1, 4, 1, 0, 0, 0, 0 };
88 FILETIME temp;
89 ULARGE_INTEGER i1;
91 REQUIRE(t != NULL);
92 REQUIRE(nanoseconds < NS_PER_S);
94 SystemTimeToFileTime(&epoch, &temp);
96 i1.LowPart = t->absolute.dwLowDateTime;
97 i1.HighPart = t->absolute.dwHighDateTime;
99 i1.QuadPart += (unsigned __int64)nanoseconds/100;
100 i1.QuadPart += (unsigned __int64)seconds*10000000;
102 t->absolute.dwLowDateTime = i1.LowPart;
103 t->absolute.dwHighDateTime = i1.HighPart;
106 void
107 isc_time_settoepoch(isc_time_t *t) {
108 REQUIRE(t != NULL);
110 t->absolute.dwLowDateTime = 0;
111 t->absolute.dwHighDateTime = 0;
114 isc_boolean_t
115 isc_time_isepoch(const isc_time_t *t) {
116 REQUIRE(t != NULL);
118 if (t->absolute.dwLowDateTime == 0 &&
119 t->absolute.dwHighDateTime == 0)
120 return (ISC_TRUE);
122 return (ISC_FALSE);
125 isc_result_t
126 isc_time_now(isc_time_t *t) {
127 REQUIRE(t != NULL);
129 GetSystemTimeAsFileTime(&t->absolute);
131 return (ISC_R_SUCCESS);
134 isc_result_t
135 isc_time_nowplusinterval(isc_time_t *t, const isc_interval_t *i) {
136 ULARGE_INTEGER i1;
138 REQUIRE(t != NULL);
139 REQUIRE(i != NULL);
141 GetSystemTimeAsFileTime(&t->absolute);
143 i1.LowPart = t->absolute.dwLowDateTime;
144 i1.HighPart = t->absolute.dwHighDateTime;
146 if (UINT64_MAX - i1.QuadPart < (unsigned __int64)i->interval)
147 return (ISC_R_RANGE);
149 i1.QuadPart += i->interval;
151 t->absolute.dwLowDateTime = i1.LowPart;
152 t->absolute.dwHighDateTime = i1.HighPart;
154 return (ISC_R_SUCCESS);
158 isc_time_compare(const isc_time_t *t1, const isc_time_t *t2) {
159 REQUIRE(t1 != NULL && t2 != NULL);
161 return ((int)CompareFileTime(&t1->absolute, &t2->absolute));
164 isc_result_t
165 isc_time_add(const isc_time_t *t, const isc_interval_t *i, isc_time_t *result)
167 ULARGE_INTEGER i1;
169 REQUIRE(t != NULL && i != NULL && result != NULL);
171 i1.LowPart = t->absolute.dwLowDateTime;
172 i1.HighPart = t->absolute.dwHighDateTime;
174 if (UINT64_MAX - i1.QuadPart < (unsigned __int64)i->interval)
175 return (ISC_R_RANGE);
177 i1.QuadPart += i->interval;
179 result->absolute.dwLowDateTime = i1.LowPart;
180 result->absolute.dwHighDateTime = i1.HighPart;
182 return (ISC_R_SUCCESS);
185 isc_result_t
186 isc_time_subtract(const isc_time_t *t, const isc_interval_t *i,
187 isc_time_t *result) {
188 ULARGE_INTEGER i1;
190 REQUIRE(t != NULL && i != NULL && result != NULL);
192 i1.LowPart = t->absolute.dwLowDateTime;
193 i1.HighPart = t->absolute.dwHighDateTime;
195 if (i1.QuadPart < (unsigned __int64) i->interval)
196 return (ISC_R_RANGE);
198 i1.QuadPart -= i->interval;
200 result->absolute.dwLowDateTime = i1.LowPart;
201 result->absolute.dwHighDateTime = i1.HighPart;
203 return (ISC_R_SUCCESS);
206 isc_uint64_t
207 isc_time_microdiff(const isc_time_t *t1, const isc_time_t *t2) {
208 ULARGE_INTEGER i1, i2;
209 LONGLONG i3;
211 REQUIRE(t1 != NULL && t2 != NULL);
213 i1.LowPart = t1->absolute.dwLowDateTime;
214 i1.HighPart = t1->absolute.dwHighDateTime;
215 i2.LowPart = t2->absolute.dwLowDateTime;
216 i2.HighPart = t2->absolute.dwHighDateTime;
218 if (i1.QuadPart <= i2.QuadPart)
219 return (0);
222 * Convert to microseconds.
224 i3 = (i1.QuadPart - i2.QuadPart) / 10;
226 return (i3);
229 isc_uint32_t
230 isc_time_seconds(const isc_time_t *t) {
231 SYSTEMTIME st;
234 * Convert the time to a SYSTEMTIME structure and the grab the
235 * milliseconds
237 FileTimeToSystemTime(&t->absolute, &st);
239 return ((isc_uint32_t)(st.wMilliseconds / 1000));
242 isc_uint32_t
243 isc_time_nanoseconds(const isc_time_t *t) {
244 SYSTEMTIME st;
247 * Convert the time to a SYSTEMTIME structure and the grab the
248 * milliseconds
250 FileTimeToSystemTime(&t->absolute, &st);
252 return ((isc_uint32_t)(st.wMilliseconds * 1000000));
255 void
256 isc_time_formattimestamp(const isc_time_t *t, char *buf, unsigned int len) {
257 FILETIME localft;
258 SYSTEMTIME st;
259 char DateBuf[50];
260 char TimeBuf[50];
262 static const char badtime[] = "99-Bad-9999 99:99:99.999";
264 REQUIRE(len > 0);
265 if (FileTimeToLocalFileTime(&t->absolute, &localft) &&
266 FileTimeToSystemTime(&localft, &st)) {
267 GetDateFormat(LOCALE_USER_DEFAULT, 0, &st, "dd-MMM-yyyy",
268 DateBuf, 50);
269 GetTimeFormat(LOCALE_USER_DEFAULT, TIME_NOTIMEMARKER|
270 TIME_FORCE24HOURFORMAT, &st, NULL, TimeBuf, 50);
272 snprintf(buf, len, "%s %s.%03u", DateBuf, TimeBuf,
273 st.wMilliseconds);
275 } else
276 snprintf(buf, len, badtime);
279 void
280 isc_time_formathttptimestamp(const isc_time_t *t, char *buf, unsigned int len) {
281 SYSTEMTIME st;
282 char DateBuf[50];
283 char TimeBuf[50];
285 REQUIRE(len > 0);
286 if (FileTimeToSystemTime(&t->absolute, &st)) {
287 GetDateFormat(LOCALE_USER_DEFAULT, 0, &st, "ddd',', dd-MMM-yyyy",
288 DateBuf, 50);
289 GetTimeFormat(LOCALE_USER_DEFAULT,
290 TIME_NOTIMEMARKER | TIME_FORCE24HOURFORMAT,
291 &st, "hh':'mm':'ss", TimeBuf, 50);
293 snprintf(buf, len, "%s %s GMT", DateBuf, TimeBuf);
294 } else {
295 buf[0] = 0;