Apache HTTPD
time.c
Go to the documentation of this file.
1/* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "apr_arch_atime.h"
18#include "apr_time.h"
19#include "apr_general.h"
20#include "apr_lib.h"
21#include "apr_portable.h"
22#if APR_HAVE_TIME_H
23#include <time.h>
24#endif
25#if APR_HAVE_ERRNO_H
26#include <errno.h>
27#endif
28#include <string.h>
29#include <winbase.h>
30#include "apr_arch_misc.h"
31
32/* Leap year is any year divisible by four, but not by 100 unless also
33 * divisible by 400
34 */
35#define IsLeapYear(y) ((!(y % 4)) ? (((y % 400) && !(y % 100)) ? 0 : 1) : 0)
36
38{
40 static DWORD result;
41 static int init = 0;
42
43 if (!init) {
45 init = 1;
46 }
47
48 *tzresult = &tz;
49 return result;
50}
51
53{
54 static const int dayoffset[12] =
55 {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
56
57 if (tm->wMonth < 1 || tm->wMonth > 12)
58 return;
59
60 /* Note; the caller is responsible for filling in detailed tm_usec,
61 * tm_gmtoff and tm_isdst data when applicable.
62 */
63 xt->tm_usec = tm->wMilliseconds * 1000;
64 xt->tm_sec = tm->wSecond;
65 xt->tm_min = tm->wMinute;
66 xt->tm_hour = tm->wHour;
67 xt->tm_mday = tm->wDay;
68 xt->tm_mon = tm->wMonth - 1;
69 xt->tm_year = tm->wYear - 1900;
70 xt->tm_wday = tm->wDayOfWeek;
71 xt->tm_yday = dayoffset[xt->tm_mon] + (tm->wDay - 1);
72 xt->tm_isdst = 0;
73 xt->tm_gmtoff = 0;
74
75 /* If this is a leap year, and we're past the 28th of Feb. (the
76 * 58th day after Jan. 1), we'll increment our tm_yday by one.
77 */
78 if (IsLeapYear(tm->wYear) && (xt->tm_yday > 58))
79 xt->tm_yday++;
80}
81
88
89/* Return micro-seconds since the Unix epoch (jan. 1, 1970) UTC */
91{
92 LONGLONG aprtime = 0;
93 FILETIME time;
94#ifndef _WIN32_WCE
96#else
99 SystemTimeToFileTime(&st, &time);
100#endif
101 FileTimeToAprTime(&aprtime, &time);
102 return aprtime;
103}
104
107{
108 FILETIME ft;
112 /* The Platform SDK documents that SYSTEMTIME/FILETIME are
113 * generally UTC, so no timezone info needed
114 * The time value makes a roundtrip, st cannot be invalid below.
115 */
117 result->tm_usec = (apr_int32_t) (input % APR_USEC_PER_SEC);
118 return APR_SUCCESS;
119}
120
124{
125 FILETIME ft;
129 /* The Platform SDK documents that SYSTEMTIME/FILETIME are
130 * generally UTC, so we will simply note the offs used.
131 * The time value makes a roundtrip, st cannot be invalid below.
132 */
134 result->tm_usec = (apr_int32_t) (input % APR_USEC_PER_SEC);
135 result->tm_gmtoff = offs;
136 return APR_SUCCESS;
137}
138
141{
144
146
147#if APR_HAS_UNICODE_FS && !defined(_WIN32_WCE)
149 {
153
155
157
158 /* The Platform SDK documents that SYSTEMTIME/FILETIME are
159 * generally UTC. We use SystemTimeToTzSpecificLocalTime
160 * because FileTimeToLocalFileFime is documented that the
161 * resulting time local file time would have DST relative
162 * to the *present* date, not the date converted.
163 * The time value makes a roundtrip, localst cannot be invalid below.
164 */
167 result->tm_usec = (apr_int32_t) (input % APR_USEC_PER_SEC);
168
169
170 /* Recover the resulting time as an apr time and use the
171 * delta for gmtoff in seconds (and ignore msec rounding)
172 */
175 result->tm_gmtoff = (int)apr_time_sec(localtime)
177
178 /* To compute the dst flag, we compare the expected
179 * local (standard) timezone bias to the delta.
180 * [Note, in war time or double daylight time the
181 * resulting tm_isdst is, desireably, 2 hours]
182 */
183 result->tm_isdst = (result->tm_gmtoff / 3600)
184 - (-(tz->Bias + tz->StandardBias) / 60);
185 }
186#endif
187#if APR_HAS_ANSI_FS || defined(_WIN32_WCE)
189 {
191 /* XXX: This code is simply *wrong*. The time converted will always
192 * map to the *now current* status of daylight savings time.
193 * The time value makes a roundtrip, st cannot be invalid below.
194 */
195
199 result->tm_usec = (apr_int32_t) (input % APR_USEC_PER_SEC);
200
201 switch (GetTimeZoneInformation(&tz)) {
203 result->tm_isdst = 0;
204 /* Bias = UTC - local time in minutes
205 * tm_gmtoff is seconds east of UTC
206 */
207 result->tm_gmtoff = tz.Bias * -60;
208 break;
210 result->tm_isdst = 0;
211 result->tm_gmtoff = (tz.Bias + tz.StandardBias) * -60;
212 break;
214 result->tm_isdst = 1;
215 result->tm_gmtoff = (tz.Bias + tz.DaylightBias) * -60;
216 break;
217 default:
218 /* noop */;
219 }
220 }
221#endif
222
223 return APR_SUCCESS;
224}
225
227 apr_time_exp_t *xt)
228{
229 apr_time_t year = xt->tm_year;
231 static const int dayoffset[12] =
232 {306, 337, 0, 31, 61, 92, 122, 153, 184, 214, 245, 275};
233
234 if (xt->tm_mon < 0 || xt->tm_mon >= 12)
235 return APR_EBADDATE;
236
237 /* shift new year to 1st March in order to make leap year calc easy */
238
239 if (xt->tm_mon < 2)
240 year--;
241
242 /* Find number of days since 1st March 1900 (in the Gregorian calendar). */
243
244 days = year * 365 + year / 4 - year / 100 + (year / 100 + 3) / 4;
245 days += dayoffset[xt->tm_mon] + xt->tm_mday - 1;
246 days -= 25508; /* 1 jan 1970 is 25508 days since 1 mar 1900 */
247
248 days = ((days * 24 + xt->tm_hour) * 60 + xt->tm_min) * 60 + xt->tm_sec;
249
250 if (days < 0) {
251 return APR_EBADDATE;
252 }
253 *t = days * APR_USEC_PER_SEC + xt->tm_usec;
254 return APR_SUCCESS;
255}
256
258 apr_time_exp_t *xt)
259{
261 if (status == APR_SUCCESS)
263 return status;
264}
265
268{
269 /* TODO: Consider not passing in pointer to apr_time_t (e.g., call by value) */
271 return APR_SUCCESS;
272}
273
276{
277 (*ostime)->wYear = aprexptime->tm_year + 1900;
278 (*ostime)->wMonth = aprexptime->tm_mon + 1;
279 (*ostime)->wDayOfWeek = aprexptime->tm_wday;
280 (*ostime)->wDay = aprexptime->tm_mday;
281 (*ostime)->wHour = aprexptime->tm_hour;
282 (*ostime)->wMinute = aprexptime->tm_min;
283 (*ostime)->wSecond = aprexptime->tm_sec;
284 (*ostime)->wMilliseconds = aprexptime->tm_usec / 1000;
285 return APR_SUCCESS;
286}
287
291{
292 /* XXX: sanity failure, what is file time, gmt or local ?
293 */
295 return APR_SUCCESS;
296}
297
301{
302 /* The Platform SDK documents that SYSTEMTIME/FILETIME are
303 * generally UTC, so no timezone info needed
304 */
305 if ((*ostime)->wMonth < 1 || (*ostime)->wMonth > 12)
306 return APR_EBADDATE;
307
309 return APR_SUCCESS;
310}
311
313{
314 /* One of the few sane situations for a cast, Sleep
315 * is in ms, not us, and passed as a DWORD value
316 */
317 Sleep((DWORD)((t + 999) / 1000));
318}
319
320#if defined(_WIN32_WCE)
321/* A noop on WinCE, like Unix implementation */
323{
324 return;
325}
326#else
333
335{
337 /* Timer resolution is stated in 100ns units. Note that TRUE requests the
338 * new clock resolution, FALSE above releases the request.
339 */
340 if (SetTimerResolution(10000, TRUE, &newRes) == 0 /* STATUS_SUCCESS */) {
341 /* register the cleanup... */
344 }
345}
346#endif
#define TRUE
Definition abts.h:38
#define FALSE
Definition abts.h:35
static APR_INLINE void FileTimeToAprTime(apr_time_t *result, FILETIME *input)
static APR_INLINE void AprTimeToFileTime(LPFILETIME pft, apr_time_t t)
APR Miscellaneous library routines.
APR general purpose library routines.
APR Portability Routines.
APR Time Library.
#define APR_EBADDATE
Definition apr_errno.h:293
apr_size_t size
const char * input
Definition apr_cstr.h:93
#define APR_SUCCESS
Definition apr_errno.h:225
int apr_status_t
Definition apr_errno.h:44
apr_array_header_t ** result
apr_pool_t * cont
Definition apr_getopt.h:103
APR_DECLARE(void)
Definition time.c:237
apr_interval_time_t t
struct tm apr_os_exp_time_t
struct timeval apr_os_imp_time_t
apr_time_exp_t * aprtime
apr_os_imp_time_t ** ostime
int int status
apr_size_t apr_size_t const char apr_time_exp_t * tm
Definition apr_time.h:221
apr_time_t apr_int32_t offs
Definition apr_time.h:142
apr_int64_t apr_interval_time_t
Definition apr_time.h:55
#define APR_USEC_PER_SEC
Definition apr_time.h:60
apr_int64_t apr_time_t
Definition apr_time.h:45
#define apr_time_sec(time)
Definition apr_time.h:63
apr_pool_t * p
Definition md_event.c:32
apr_int32_t tm_gmtoff
Definition apr_time.h:119
apr_int32_t tm_sec
Definition apr_time.h:101
apr_int32_t tm_hour
Definition apr_time.h:105
apr_int32_t tm_year
Definition apr_time.h:111
apr_int32_t tm_isdst
Definition apr_time.h:117
apr_int32_t tm_min
Definition apr_time.h:103
apr_int32_t tm_wday
Definition apr_time.h:113
apr_int32_t tm_mday
Definition apr_time.h:107
apr_int32_t tm_mon
Definition apr_time.h:109
apr_int32_t tm_yday
Definition apr_time.h:115
apr_int32_t tm_usec
Definition apr_time.h:99
#define ELSE_WIN_OS_IS_ANSI
typedef int(WSAAPI *apr_winapi_fpt_WSAPoll)(IN OUT LPWSAPOLLFD fdArray
#define IF_WIN_OS_IS_UNICODE
#define SetTimerResolution
typedef DWORD(WINAPI *apr_winapi_fpt_GetCompressedFileSizeA)(IN LPCSTR lpFileName
static DWORD get_local_timezone(TIME_ZONE_INFORMATION **tzresult)
Definition time.c:37
static void SystemTimeToAprExpTime(apr_time_exp_t *xt, SYSTEMTIME *tm)
Definition time.c:52
#define IsLeapYear(y)
Definition time.c:35
static apr_status_t clock_restore(void *unsetres)
Definition time.c:327