1*00b67f09SDavid van Moolenbroek /* $NetBSD: time.c,v 1.6 2014/12/10 04:38:01 christos Exp $ */
2*00b67f09SDavid van Moolenbroek
3*00b67f09SDavid van Moolenbroek /*
4*00b67f09SDavid van Moolenbroek * Copyright (C) 2004, 2006-2009, 2012-2014 Internet Systems Consortium, Inc. ("ISC")
5*00b67f09SDavid van Moolenbroek * Copyright (C) 1998-2001, 2003 Internet Software Consortium.
6*00b67f09SDavid van Moolenbroek *
7*00b67f09SDavid van Moolenbroek * Permission to use, copy, modify, and/or distribute this software for any
8*00b67f09SDavid van Moolenbroek * purpose with or without fee is hereby granted, provided that the above
9*00b67f09SDavid van Moolenbroek * copyright notice and this permission notice appear in all copies.
10*00b67f09SDavid van Moolenbroek *
11*00b67f09SDavid van Moolenbroek * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12*00b67f09SDavid van Moolenbroek * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13*00b67f09SDavid van Moolenbroek * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14*00b67f09SDavid van Moolenbroek * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15*00b67f09SDavid van Moolenbroek * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16*00b67f09SDavid van Moolenbroek * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17*00b67f09SDavid van Moolenbroek * PERFORMANCE OF THIS SOFTWARE.
18*00b67f09SDavid van Moolenbroek */
19*00b67f09SDavid van Moolenbroek
20*00b67f09SDavid van Moolenbroek /* Id: time.c,v 1.52 2009/08/14 07:51:08 marka Exp */
21*00b67f09SDavid van Moolenbroek
22*00b67f09SDavid van Moolenbroek #include <config.h>
23*00b67f09SDavid van Moolenbroek
24*00b67f09SDavid van Moolenbroek #include <errno.h>
25*00b67f09SDavid van Moolenbroek #include <limits.h>
26*00b67f09SDavid van Moolenbroek #include <stddef.h>
27*00b67f09SDavid van Moolenbroek #include <stdlib.h>
28*00b67f09SDavid van Moolenbroek #include <string.h>
29*00b67f09SDavid van Moolenbroek #include <time.h>
30*00b67f09SDavid van Moolenbroek
31*00b67f09SDavid van Moolenbroek #include <windows.h>
32*00b67f09SDavid van Moolenbroek
33*00b67f09SDavid van Moolenbroek #include <isc/assertions.h>
34*00b67f09SDavid van Moolenbroek #include <isc/time.h>
35*00b67f09SDavid van Moolenbroek #include <isc/tm.h>
36*00b67f09SDavid van Moolenbroek #include <isc/util.h>
37*00b67f09SDavid van Moolenbroek
38*00b67f09SDavid van Moolenbroek /*
39*00b67f09SDavid van Moolenbroek * struct FILETIME uses "100-nanoseconds intervals".
40*00b67f09SDavid van Moolenbroek * NS / S = 1000000000 (10^9).
41*00b67f09SDavid van Moolenbroek * While it is reasonably obvious that this makes the needed
42*00b67f09SDavid van Moolenbroek * conversion factor 10^7, it is coded this way for additional clarity.
43*00b67f09SDavid van Moolenbroek */
44*00b67f09SDavid van Moolenbroek #define NS_PER_S 1000000000
45*00b67f09SDavid van Moolenbroek #define NS_INTERVAL 100
46*00b67f09SDavid van Moolenbroek #define INTERVALS_PER_S (NS_PER_S / NS_INTERVAL)
47*00b67f09SDavid van Moolenbroek #define UINT64_MAX _UI64_MAX
48*00b67f09SDavid van Moolenbroek
49*00b67f09SDavid van Moolenbroek /***
50*00b67f09SDavid van Moolenbroek *** Absolute Times
51*00b67f09SDavid van Moolenbroek ***/
52*00b67f09SDavid van Moolenbroek
53*00b67f09SDavid van Moolenbroek static const isc_time_t epoch = { { 0, 0 } };
54*00b67f09SDavid van Moolenbroek LIBISC_EXTERNAL_DATA const isc_time_t * const isc_time_epoch = &epoch;
55*00b67f09SDavid van Moolenbroek
56*00b67f09SDavid van Moolenbroek /***
57*00b67f09SDavid van Moolenbroek *** Intervals
58*00b67f09SDavid van Moolenbroek ***/
59*00b67f09SDavid van Moolenbroek
60*00b67f09SDavid van Moolenbroek static const isc_interval_t zero_interval = { 0 };
61*00b67f09SDavid van Moolenbroek LIBISC_EXTERNAL_DATA const isc_interval_t * const isc_interval_zero = &zero_interval;
62*00b67f09SDavid van Moolenbroek
63*00b67f09SDavid van Moolenbroek void
isc_interval_set(isc_interval_t * i,unsigned int seconds,unsigned int nanoseconds)64*00b67f09SDavid van Moolenbroek isc_interval_set(isc_interval_t *i, unsigned int seconds,
65*00b67f09SDavid van Moolenbroek unsigned int nanoseconds)
66*00b67f09SDavid van Moolenbroek {
67*00b67f09SDavid van Moolenbroek REQUIRE(i != NULL);
68*00b67f09SDavid van Moolenbroek REQUIRE(nanoseconds < NS_PER_S);
69*00b67f09SDavid van Moolenbroek
70*00b67f09SDavid van Moolenbroek /*
71*00b67f09SDavid van Moolenbroek * This rounds nanoseconds up not down.
72*00b67f09SDavid van Moolenbroek */
73*00b67f09SDavid van Moolenbroek i->interval = (LONGLONG)seconds * INTERVALS_PER_S
74*00b67f09SDavid van Moolenbroek + (nanoseconds + NS_INTERVAL - 1) / NS_INTERVAL;
75*00b67f09SDavid van Moolenbroek }
76*00b67f09SDavid van Moolenbroek
77*00b67f09SDavid van Moolenbroek isc_boolean_t
isc_interval_iszero(const isc_interval_t * i)78*00b67f09SDavid van Moolenbroek isc_interval_iszero(const isc_interval_t *i) {
79*00b67f09SDavid van Moolenbroek REQUIRE(i != NULL);
80*00b67f09SDavid van Moolenbroek if (i->interval == 0)
81*00b67f09SDavid van Moolenbroek return (ISC_TRUE);
82*00b67f09SDavid van Moolenbroek
83*00b67f09SDavid van Moolenbroek return (ISC_FALSE);
84*00b67f09SDavid van Moolenbroek }
85*00b67f09SDavid van Moolenbroek
86*00b67f09SDavid van Moolenbroek void
isc_time_set(isc_time_t * t,unsigned int seconds,unsigned int nanoseconds)87*00b67f09SDavid van Moolenbroek isc_time_set(isc_time_t *t, unsigned int seconds, unsigned int nanoseconds) {
88*00b67f09SDavid van Moolenbroek SYSTEMTIME epoch = { 1970, 1, 4, 1, 0, 0, 0, 0 };
89*00b67f09SDavid van Moolenbroek FILETIME temp;
90*00b67f09SDavid van Moolenbroek ULARGE_INTEGER i1;
91*00b67f09SDavid van Moolenbroek
92*00b67f09SDavid van Moolenbroek REQUIRE(t != NULL);
93*00b67f09SDavid van Moolenbroek REQUIRE(nanoseconds < NS_PER_S);
94*00b67f09SDavid van Moolenbroek
95*00b67f09SDavid van Moolenbroek SystemTimeToFileTime(&epoch, &temp);
96*00b67f09SDavid van Moolenbroek
97*00b67f09SDavid van Moolenbroek i1.LowPart = temp.dwLowDateTime;
98*00b67f09SDavid van Moolenbroek i1.HighPart = temp.dwHighDateTime;
99*00b67f09SDavid van Moolenbroek
100*00b67f09SDavid van Moolenbroek i1.QuadPart += (unsigned __int64)nanoseconds/100;
101*00b67f09SDavid van Moolenbroek i1.QuadPart += (unsigned __int64)seconds*10000000;
102*00b67f09SDavid van Moolenbroek
103*00b67f09SDavid van Moolenbroek t->absolute.dwLowDateTime = i1.LowPart;
104*00b67f09SDavid van Moolenbroek t->absolute.dwHighDateTime = i1.HighPart;
105*00b67f09SDavid van Moolenbroek }
106*00b67f09SDavid van Moolenbroek
107*00b67f09SDavid van Moolenbroek void
isc_time_settoepoch(isc_time_t * t)108*00b67f09SDavid van Moolenbroek isc_time_settoepoch(isc_time_t *t) {
109*00b67f09SDavid van Moolenbroek REQUIRE(t != NULL);
110*00b67f09SDavid van Moolenbroek
111*00b67f09SDavid van Moolenbroek t->absolute.dwLowDateTime = 0;
112*00b67f09SDavid van Moolenbroek t->absolute.dwHighDateTime = 0;
113*00b67f09SDavid van Moolenbroek }
114*00b67f09SDavid van Moolenbroek
115*00b67f09SDavid van Moolenbroek isc_boolean_t
isc_time_isepoch(const isc_time_t * t)116*00b67f09SDavid van Moolenbroek isc_time_isepoch(const isc_time_t *t) {
117*00b67f09SDavid van Moolenbroek REQUIRE(t != NULL);
118*00b67f09SDavid van Moolenbroek
119*00b67f09SDavid van Moolenbroek if (t->absolute.dwLowDateTime == 0 &&
120*00b67f09SDavid van Moolenbroek t->absolute.dwHighDateTime == 0)
121*00b67f09SDavid van Moolenbroek return (ISC_TRUE);
122*00b67f09SDavid van Moolenbroek
123*00b67f09SDavid van Moolenbroek return (ISC_FALSE);
124*00b67f09SDavid van Moolenbroek }
125*00b67f09SDavid van Moolenbroek
126*00b67f09SDavid van Moolenbroek isc_result_t
isc_time_now(isc_time_t * t)127*00b67f09SDavid van Moolenbroek isc_time_now(isc_time_t *t) {
128*00b67f09SDavid van Moolenbroek REQUIRE(t != NULL);
129*00b67f09SDavid van Moolenbroek
130*00b67f09SDavid van Moolenbroek GetSystemTimeAsFileTime(&t->absolute);
131*00b67f09SDavid van Moolenbroek
132*00b67f09SDavid van Moolenbroek return (ISC_R_SUCCESS);
133*00b67f09SDavid van Moolenbroek }
134*00b67f09SDavid van Moolenbroek
135*00b67f09SDavid van Moolenbroek isc_result_t
isc_time_nowplusinterval(isc_time_t * t,const isc_interval_t * i)136*00b67f09SDavid van Moolenbroek isc_time_nowplusinterval(isc_time_t *t, const isc_interval_t *i) {
137*00b67f09SDavid van Moolenbroek ULARGE_INTEGER i1;
138*00b67f09SDavid van Moolenbroek
139*00b67f09SDavid van Moolenbroek REQUIRE(t != NULL);
140*00b67f09SDavid van Moolenbroek REQUIRE(i != NULL);
141*00b67f09SDavid van Moolenbroek
142*00b67f09SDavid van Moolenbroek GetSystemTimeAsFileTime(&t->absolute);
143*00b67f09SDavid van Moolenbroek
144*00b67f09SDavid van Moolenbroek i1.LowPart = t->absolute.dwLowDateTime;
145*00b67f09SDavid van Moolenbroek i1.HighPart = t->absolute.dwHighDateTime;
146*00b67f09SDavid van Moolenbroek
147*00b67f09SDavid van Moolenbroek if (UINT64_MAX - i1.QuadPart < (unsigned __int64)i->interval)
148*00b67f09SDavid van Moolenbroek return (ISC_R_RANGE);
149*00b67f09SDavid van Moolenbroek
150*00b67f09SDavid van Moolenbroek i1.QuadPart += i->interval;
151*00b67f09SDavid van Moolenbroek
152*00b67f09SDavid van Moolenbroek t->absolute.dwLowDateTime = i1.LowPart;
153*00b67f09SDavid van Moolenbroek t->absolute.dwHighDateTime = i1.HighPart;
154*00b67f09SDavid van Moolenbroek
155*00b67f09SDavid van Moolenbroek return (ISC_R_SUCCESS);
156*00b67f09SDavid van Moolenbroek }
157*00b67f09SDavid van Moolenbroek
158*00b67f09SDavid van Moolenbroek int
isc_time_compare(const isc_time_t * t1,const isc_time_t * t2)159*00b67f09SDavid van Moolenbroek isc_time_compare(const isc_time_t *t1, const isc_time_t *t2) {
160*00b67f09SDavid van Moolenbroek REQUIRE(t1 != NULL && t2 != NULL);
161*00b67f09SDavid van Moolenbroek
162*00b67f09SDavid van Moolenbroek return ((int)CompareFileTime(&t1->absolute, &t2->absolute));
163*00b67f09SDavid van Moolenbroek }
164*00b67f09SDavid van Moolenbroek
165*00b67f09SDavid van Moolenbroek isc_result_t
isc_time_add(const isc_time_t * t,const isc_interval_t * i,isc_time_t * result)166*00b67f09SDavid van Moolenbroek isc_time_add(const isc_time_t *t, const isc_interval_t *i, isc_time_t *result)
167*00b67f09SDavid van Moolenbroek {
168*00b67f09SDavid van Moolenbroek ULARGE_INTEGER i1;
169*00b67f09SDavid van Moolenbroek
170*00b67f09SDavid van Moolenbroek REQUIRE(t != NULL && i != NULL && result != NULL);
171*00b67f09SDavid van Moolenbroek
172*00b67f09SDavid van Moolenbroek i1.LowPart = t->absolute.dwLowDateTime;
173*00b67f09SDavid van Moolenbroek i1.HighPart = t->absolute.dwHighDateTime;
174*00b67f09SDavid van Moolenbroek
175*00b67f09SDavid van Moolenbroek if (UINT64_MAX - i1.QuadPart < (unsigned __int64)i->interval)
176*00b67f09SDavid van Moolenbroek return (ISC_R_RANGE);
177*00b67f09SDavid van Moolenbroek
178*00b67f09SDavid van Moolenbroek i1.QuadPart += i->interval;
179*00b67f09SDavid van Moolenbroek
180*00b67f09SDavid van Moolenbroek result->absolute.dwLowDateTime = i1.LowPart;
181*00b67f09SDavid van Moolenbroek result->absolute.dwHighDateTime = i1.HighPart;
182*00b67f09SDavid van Moolenbroek
183*00b67f09SDavid van Moolenbroek return (ISC_R_SUCCESS);
184*00b67f09SDavid van Moolenbroek }
185*00b67f09SDavid van Moolenbroek
186*00b67f09SDavid van Moolenbroek isc_result_t
isc_time_subtract(const isc_time_t * t,const isc_interval_t * i,isc_time_t * result)187*00b67f09SDavid van Moolenbroek isc_time_subtract(const isc_time_t *t, const isc_interval_t *i,
188*00b67f09SDavid van Moolenbroek isc_time_t *result) {
189*00b67f09SDavid van Moolenbroek ULARGE_INTEGER i1;
190*00b67f09SDavid van Moolenbroek
191*00b67f09SDavid van Moolenbroek REQUIRE(t != NULL && i != NULL && result != NULL);
192*00b67f09SDavid van Moolenbroek
193*00b67f09SDavid van Moolenbroek i1.LowPart = t->absolute.dwLowDateTime;
194*00b67f09SDavid van Moolenbroek i1.HighPart = t->absolute.dwHighDateTime;
195*00b67f09SDavid van Moolenbroek
196*00b67f09SDavid van Moolenbroek if (i1.QuadPart < (unsigned __int64) i->interval)
197*00b67f09SDavid van Moolenbroek return (ISC_R_RANGE);
198*00b67f09SDavid van Moolenbroek
199*00b67f09SDavid van Moolenbroek i1.QuadPart -= i->interval;
200*00b67f09SDavid van Moolenbroek
201*00b67f09SDavid van Moolenbroek result->absolute.dwLowDateTime = i1.LowPart;
202*00b67f09SDavid van Moolenbroek result->absolute.dwHighDateTime = i1.HighPart;
203*00b67f09SDavid van Moolenbroek
204*00b67f09SDavid van Moolenbroek return (ISC_R_SUCCESS);
205*00b67f09SDavid van Moolenbroek }
206*00b67f09SDavid van Moolenbroek
207*00b67f09SDavid van Moolenbroek isc_uint64_t
isc_time_microdiff(const isc_time_t * t1,const isc_time_t * t2)208*00b67f09SDavid van Moolenbroek isc_time_microdiff(const isc_time_t *t1, const isc_time_t *t2) {
209*00b67f09SDavid van Moolenbroek ULARGE_INTEGER i1, i2;
210*00b67f09SDavid van Moolenbroek LONGLONG i3;
211*00b67f09SDavid van Moolenbroek
212*00b67f09SDavid van Moolenbroek REQUIRE(t1 != NULL && t2 != NULL);
213*00b67f09SDavid van Moolenbroek
214*00b67f09SDavid van Moolenbroek i1.LowPart = t1->absolute.dwLowDateTime;
215*00b67f09SDavid van Moolenbroek i1.HighPart = t1->absolute.dwHighDateTime;
216*00b67f09SDavid van Moolenbroek i2.LowPart = t2->absolute.dwLowDateTime;
217*00b67f09SDavid van Moolenbroek i2.HighPart = t2->absolute.dwHighDateTime;
218*00b67f09SDavid van Moolenbroek
219*00b67f09SDavid van Moolenbroek if (i1.QuadPart <= i2.QuadPart)
220*00b67f09SDavid van Moolenbroek return (0);
221*00b67f09SDavid van Moolenbroek
222*00b67f09SDavid van Moolenbroek /*
223*00b67f09SDavid van Moolenbroek * Convert to microseconds.
224*00b67f09SDavid van Moolenbroek */
225*00b67f09SDavid van Moolenbroek i3 = (i1.QuadPart - i2.QuadPart) / 10;
226*00b67f09SDavid van Moolenbroek
227*00b67f09SDavid van Moolenbroek return (i3);
228*00b67f09SDavid van Moolenbroek }
229*00b67f09SDavid van Moolenbroek
230*00b67f09SDavid van Moolenbroek isc_uint32_t
isc_time_seconds(const isc_time_t * t)231*00b67f09SDavid van Moolenbroek isc_time_seconds(const isc_time_t *t) {
232*00b67f09SDavid van Moolenbroek SYSTEMTIME epoch = { 1970, 1, 4, 1, 0, 0, 0, 0 };
233*00b67f09SDavid van Moolenbroek FILETIME temp;
234*00b67f09SDavid van Moolenbroek ULARGE_INTEGER i1, i2;
235*00b67f09SDavid van Moolenbroek LONGLONG i3;
236*00b67f09SDavid van Moolenbroek
237*00b67f09SDavid van Moolenbroek SystemTimeToFileTime(&epoch, &temp);
238*00b67f09SDavid van Moolenbroek
239*00b67f09SDavid van Moolenbroek i1.LowPart = t->absolute.dwLowDateTime;
240*00b67f09SDavid van Moolenbroek i1.HighPart = t->absolute.dwHighDateTime;
241*00b67f09SDavid van Moolenbroek i2.LowPart = temp.dwLowDateTime;
242*00b67f09SDavid van Moolenbroek i2.HighPart = temp.dwHighDateTime;
243*00b67f09SDavid van Moolenbroek
244*00b67f09SDavid van Moolenbroek i3 = (i1.QuadPart - i2.QuadPart) / 10000000;
245*00b67f09SDavid van Moolenbroek
246*00b67f09SDavid van Moolenbroek return ((isc_uint32_t)i3);
247*00b67f09SDavid van Moolenbroek }
248*00b67f09SDavid van Moolenbroek
249*00b67f09SDavid van Moolenbroek isc_result_t
isc_time_secondsastimet(const isc_time_t * t,time_t * secondsp)250*00b67f09SDavid van Moolenbroek isc_time_secondsastimet(const isc_time_t *t, time_t *secondsp) {
251*00b67f09SDavid van Moolenbroek time_t seconds;
252*00b67f09SDavid van Moolenbroek
253*00b67f09SDavid van Moolenbroek REQUIRE(t != NULL);
254*00b67f09SDavid van Moolenbroek
255*00b67f09SDavid van Moolenbroek seconds = (time_t)isc_time_seconds(t);
256*00b67f09SDavid van Moolenbroek
257*00b67f09SDavid van Moolenbroek INSIST(sizeof(unsigned int) == sizeof(isc_uint32_t));
258*00b67f09SDavid van Moolenbroek INSIST(sizeof(time_t) >= sizeof(isc_uint32_t));
259*00b67f09SDavid van Moolenbroek
260*00b67f09SDavid van Moolenbroek if (isc_time_seconds(t) > (~0U>>1) && seconds <= (time_t)(~0U>>1))
261*00b67f09SDavid van Moolenbroek return (ISC_R_RANGE);
262*00b67f09SDavid van Moolenbroek
263*00b67f09SDavid van Moolenbroek *secondsp = seconds;
264*00b67f09SDavid van Moolenbroek
265*00b67f09SDavid van Moolenbroek return (ISC_R_SUCCESS);
266*00b67f09SDavid van Moolenbroek }
267*00b67f09SDavid van Moolenbroek
268*00b67f09SDavid van Moolenbroek
269*00b67f09SDavid van Moolenbroek isc_uint32_t
isc_time_nanoseconds(const isc_time_t * t)270*00b67f09SDavid van Moolenbroek isc_time_nanoseconds(const isc_time_t *t) {
271*00b67f09SDavid van Moolenbroek ULARGE_INTEGER i;
272*00b67f09SDavid van Moolenbroek
273*00b67f09SDavid van Moolenbroek i.LowPart = t->absolute.dwLowDateTime;
274*00b67f09SDavid van Moolenbroek i.HighPart = t->absolute.dwHighDateTime;
275*00b67f09SDavid van Moolenbroek return ((isc_uint32_t)(i.QuadPart % 10000000) * 100);
276*00b67f09SDavid van Moolenbroek }
277*00b67f09SDavid van Moolenbroek
278*00b67f09SDavid van Moolenbroek void
isc_time_formattimestamp(const isc_time_t * t,char * buf,unsigned int len)279*00b67f09SDavid van Moolenbroek isc_time_formattimestamp(const isc_time_t *t, char *buf, unsigned int len) {
280*00b67f09SDavid van Moolenbroek FILETIME localft;
281*00b67f09SDavid van Moolenbroek SYSTEMTIME st;
282*00b67f09SDavid van Moolenbroek char DateBuf[50];
283*00b67f09SDavid van Moolenbroek char TimeBuf[50];
284*00b67f09SDavid van Moolenbroek
285*00b67f09SDavid van Moolenbroek static const char badtime[] = "99-Bad-9999 99:99:99.999";
286*00b67f09SDavid van Moolenbroek
287*00b67f09SDavid van Moolenbroek REQUIRE(len > 0);
288*00b67f09SDavid van Moolenbroek if (FileTimeToLocalFileTime(&t->absolute, &localft) &&
289*00b67f09SDavid van Moolenbroek FileTimeToSystemTime(&localft, &st)) {
290*00b67f09SDavid van Moolenbroek GetDateFormat(LOCALE_USER_DEFAULT, 0, &st, "dd-MMM-yyyy",
291*00b67f09SDavid van Moolenbroek DateBuf, 50);
292*00b67f09SDavid van Moolenbroek GetTimeFormat(LOCALE_USER_DEFAULT, TIME_NOTIMEMARKER|
293*00b67f09SDavid van Moolenbroek TIME_FORCE24HOURFORMAT, &st, NULL, TimeBuf, 50);
294*00b67f09SDavid van Moolenbroek
295*00b67f09SDavid van Moolenbroek snprintf(buf, len, "%s %s.%03u", DateBuf, TimeBuf,
296*00b67f09SDavid van Moolenbroek st.wMilliseconds);
297*00b67f09SDavid van Moolenbroek
298*00b67f09SDavid van Moolenbroek } else
299*00b67f09SDavid van Moolenbroek snprintf(buf, len, badtime);
300*00b67f09SDavid van Moolenbroek }
301*00b67f09SDavid van Moolenbroek
302*00b67f09SDavid van Moolenbroek void
isc_time_formathttptimestamp(const isc_time_t * t,char * buf,unsigned int len)303*00b67f09SDavid van Moolenbroek isc_time_formathttptimestamp(const isc_time_t *t, char *buf, unsigned int len) {
304*00b67f09SDavid van Moolenbroek SYSTEMTIME st;
305*00b67f09SDavid van Moolenbroek char DateBuf[50];
306*00b67f09SDavid van Moolenbroek char TimeBuf[50];
307*00b67f09SDavid van Moolenbroek
308*00b67f09SDavid van Moolenbroek /* strftime() format: "%a, %d %b %Y %H:%M:%S GMT" */
309*00b67f09SDavid van Moolenbroek
310*00b67f09SDavid van Moolenbroek REQUIRE(len > 0);
311*00b67f09SDavid van Moolenbroek if (FileTimeToSystemTime(&t->absolute, &st)) {
312*00b67f09SDavid van Moolenbroek GetDateFormat(LOCALE_USER_DEFAULT, 0, &st,
313*00b67f09SDavid van Moolenbroek "ddd',' dd MMM yyyy", DateBuf, 50);
314*00b67f09SDavid van Moolenbroek GetTimeFormat(LOCALE_USER_DEFAULT,
315*00b67f09SDavid van Moolenbroek TIME_NOTIMEMARKER | TIME_FORCE24HOURFORMAT,
316*00b67f09SDavid van Moolenbroek &st, "hh':'mm':'ss", TimeBuf, 50);
317*00b67f09SDavid van Moolenbroek
318*00b67f09SDavid van Moolenbroek snprintf(buf, len, "%s %s GMT", DateBuf, TimeBuf);
319*00b67f09SDavid van Moolenbroek } else {
320*00b67f09SDavid van Moolenbroek buf[0] = 0;
321*00b67f09SDavid van Moolenbroek }
322*00b67f09SDavid van Moolenbroek }
323*00b67f09SDavid van Moolenbroek
324*00b67f09SDavid van Moolenbroek isc_result_t
isc_time_parsehttptimestamp(char * buf,isc_time_t * t)325*00b67f09SDavid van Moolenbroek isc_time_parsehttptimestamp(char *buf, isc_time_t *t) {
326*00b67f09SDavid van Moolenbroek struct tm t_tm;
327*00b67f09SDavid van Moolenbroek time_t when;
328*00b67f09SDavid van Moolenbroek char *p;
329*00b67f09SDavid van Moolenbroek
330*00b67f09SDavid van Moolenbroek REQUIRE(buf != NULL);
331*00b67f09SDavid van Moolenbroek REQUIRE(t != NULL);
332*00b67f09SDavid van Moolenbroek p = isc_tm_strptime(buf, "%a, %d %b %Y %H:%M:%S", &t_tm);
333*00b67f09SDavid van Moolenbroek if (p == NULL)
334*00b67f09SDavid van Moolenbroek return (ISC_R_UNEXPECTED);
335*00b67f09SDavid van Moolenbroek when = isc_tm_timegm(&t_tm);
336*00b67f09SDavid van Moolenbroek if (when == -1)
337*00b67f09SDavid van Moolenbroek return (ISC_R_UNEXPECTED);
338*00b67f09SDavid van Moolenbroek isc_time_set(t, (unsigned int)when, 0);
339*00b67f09SDavid van Moolenbroek return (ISC_R_SUCCESS);
340*00b67f09SDavid van Moolenbroek }
341*00b67f09SDavid van Moolenbroek
342*00b67f09SDavid van Moolenbroek void
isc_time_formatISO8601(const isc_time_t * t,char * buf,unsigned int len)343*00b67f09SDavid van Moolenbroek isc_time_formatISO8601(const isc_time_t *t, char *buf, unsigned int len) {
344*00b67f09SDavid van Moolenbroek SYSTEMTIME st;
345*00b67f09SDavid van Moolenbroek char DateBuf[50];
346*00b67f09SDavid van Moolenbroek char TimeBuf[50];
347*00b67f09SDavid van Moolenbroek
348*00b67f09SDavid van Moolenbroek /* strtime() format: "%Y-%m-%dT%H:%M:%SZ" */
349*00b67f09SDavid van Moolenbroek
350*00b67f09SDavid van Moolenbroek REQUIRE(len > 0);
351*00b67f09SDavid van Moolenbroek if (FileTimeToSystemTime(&t->absolute, &st)) {
352*00b67f09SDavid van Moolenbroek GetDateFormat(LOCALE_NEUTRAL, 0, &st, "yyyy-MM-dd",
353*00b67f09SDavid van Moolenbroek DateBuf, 50);
354*00b67f09SDavid van Moolenbroek GetTimeFormat(LOCALE_NEUTRAL,
355*00b67f09SDavid van Moolenbroek TIME_NOTIMEMARKER | TIME_FORCE24HOURFORMAT,
356*00b67f09SDavid van Moolenbroek &st, "hh':'mm':'ss", TimeBuf, 50);
357*00b67f09SDavid van Moolenbroek snprintf(buf, len, "%sT%sZ", DateBuf, TimeBuf);
358*00b67f09SDavid van Moolenbroek } else {
359*00b67f09SDavid van Moolenbroek buf[0] = 0;
360*00b67f09SDavid van Moolenbroek }
361*00b67f09SDavid van Moolenbroek }
362