summaryrefslogtreecommitdiff
path: root/time
diff options
context:
space:
mode:
Diffstat (limited to 'time')
-rw-r--r--time/win32/time.c185
1 files changed, 121 insertions, 64 deletions
diff --git a/time/win32/time.c b/time/win32/time.c
index 571774a0e..e2ad9c18e 100644
--- a/time/win32/time.c
+++ b/time/win32/time.c
@@ -60,98 +60,155 @@
#include <time.h>
#include <errno.h>
#include <string.h>
+#include <winbase.h>
-ap_status_t ap_make_time(struct atime_t **new, ap_context_t *cont)
+/* Number of micro-seconds between the beginning of the Windows epoch
+ * (Jan. 1, 1601) and the Unix epoch (Jan. 1, 1970)
+ */
+#define AP_DELTA_EPOCH_IN_USEC 11644473600000000;
+
+static void FileTimeToAprTime(ap_time_t *result, FILETIME *input)
{
- (*new) = (struct atime_t *)ap_palloc(cont, sizeof(struct atime_t));
+ /* Convert FILETIME one 64 bit number so we can work with it. */
+ *result = input->dwHighDateTime;
+ *result = (*result) << 32;
+ *result |= input->dwLowDateTime;
+ *result /= 10; /* Convert from 100 nano-sec periods to micro-seconds. */
+ *result -= AP_DELTA_EPOCH_IN_USEC; /* Convert from Windows epoch to Unix epoch */
+ //printf("FileTimeToAprTime: aprtime - %I64d\n", *result);
+ return;
+}
+static void AprTimeToFileTime(LPFILETIME pft, ap_time_t t)
+{
+ LONGLONG ll;
+ //printf("AprTimeToFileTime: aprtime - %I64d\n", t);
+ t += AP_DELTA_EPOCH_IN_USEC;
+ ll = t * 10;
+ pft->dwLowDateTime = (DWORD)ll;
+ pft->dwHighDateTime = (DWORD) (ll >> 32);
+ return;
+}
- if ((*new) == NULL) {
- return APR_ENOMEM;
- }
+static void SystemTimeToAprExpTime(ap_exploded_time_t *xt, SYSTEMTIME *tm)
+{
+ xt->tm_usec = tm->wMilliseconds * 1000;
+ xt->tm_sec = tm->wSecond;
+ xt->tm_min = tm->wMinute;
+ xt->tm_hour = tm->wHour;
+ xt->tm_mday = tm->wDay;
+ xt->tm_mon = tm->wMonth - 1;
+ xt->tm_year = tm->wYear - 1900;
+ xt->tm_wday = tm->wDayOfWeek;
+ xt->tm_yday = 0; /* ToDo: need to compute this */
+ xt->tm_isdst = 0; /* ToDo: need to compute this */
+ xt->tm_gmtoff = 0; /* ToDo: maybe the caller should set this explicitly */
+ return;
+}
- (*new)->cntxt = cont;
- (*new)->currtime = -1;
- (*new)->explodedtime = NULL;
+ap_status_t ap_ansi_time_to_ap_time(ap_time_t *result, time_t input)
+{
+ *result = (ap_time_t) input * AP_USEC_PER_SEC;
return APR_SUCCESS;
}
-ap_status_t ap_current_time(struct atime_t *new)
+/* Return micro-seconds since the Unix epoch (jan. 1, 1970) */
+ap_time_t ap_now(void)
{
- if (!new) {
- return APR_ENOTIME;
- }
- if (new->explodedtime == NULL) {
- new->explodedtime = (SYSTEMTIME *)ap_palloc(new->cntxt, sizeof(SYSTEMTIME));
- }
- GetSystemTime(new->explodedtime);
- return APR_SUCCESS;
-}
+ ULONGLONG aprtime = 0;
+ FILETIME time;
+ GetSystemTimeAsFileTime(&time);
+ FileTimeToAprTime(&aprtime, &time);
+ return aprtime;
+}
-ap_status_t ap_explode_time(struct atime_t *atime, ap_timetype_e type)
+ap_status_t ap_explode_gmt(ap_exploded_time_t *result, ap_time_t input)
{
- if (!atime || !atime->explodedtime) {
- return APR_ENOTIME;
- }
+ FILETIME ft;
+ SYSTEMTIME st;
+ AprTimeToFileTime(&ft, input);
+ FileTimeToSystemTime(&ft, &st);
+ SystemTimeToAprExpTime(result, &st);
+ result->tm_gmtoff = 0;
return APR_SUCCESS;
}
-ap_status_t ap_implode_time(struct atime_t *atime)
+ap_status_t ap_explode_localtime(ap_exploded_time_t *result, ap_time_t input)
{
- FILETIME temp;
-
- if (!atime || !atime->explodedtime) {
- return APR_ENOTIME;
- }
+ SYSTEMTIME st;
+ FILETIME ft, localft;
- if (SystemTimeToFileTime(atime->explodedtime, &temp) == 0) {
- return APR_EEXIST;
- }
- atime->currtime = WinTimeToUnixTime(&temp);
+ AprTimeToFileTime(&ft, input);
+ FileTimeToLocalFileTime(&ft, &localft);
+ FileTimeToSystemTime(&localft, &st);
+ SystemTimeToAprExpTime(result, &st);
return APR_SUCCESS;
}
-ap_status_t ap_get_os_time(ap_os_time_t **atime, struct atime_t *thetime)
+ap_status_t ap_implode_time(ap_time_t *t, ap_exploded_time_t *xt)
{
- if (thetime == NULL) {
- return APR_ENOTIME;
+ int year;
+ time_t days;
+ static const int dayoffset[12] =
+ {306, 337, 0, 31, 61, 92, 122, 153, 184, 214, 245, 275};
+
+ year = xt->tm_year;
+
+ if (year < 70 || ((sizeof(time_t) <= 4) && (year >= 138))) {
+ return APR_EBADDATE;
}
- if (thetime->explodedtime == NULL) {
- ap_explode_time(thetime, APR_LOCALTIME);
+
+ /* shift new year to 1st March in order to make leap year calc easy */
+
+ if (xt->tm_mon < 2)
+ year--;
+
+ /* Find number of days since 1st March 1900 (in the Gregorian calendar). */
+
+ days = year * 365 + year / 4 - year / 100 + (year / 100 + 3) / 4;
+ days += dayoffset[xt->tm_mon] + xt->tm_mday - 1;
+ days -= 25508; /* 1 jan 1970 is 25508 days since 1 mar 1900 */
+
+ days = ((days * 24 + xt->tm_hour) * 60 + xt->tm_min) * 60 + xt->tm_sec;
+
+ if (days < 0) {
+ return APR_EBADDATE;
}
- *atime = thetime->explodedtime;
+ days -= xt->tm_gmtoff;
+ *t = days * AP_USEC_PER_SEC + xt->tm_usec;
return APR_SUCCESS;
}
-ap_status_t ap_put_os_time(struct atime_t **thetime, ap_os_time_t *atime,
- ap_context_t *cont)
+ap_status_t ap_get_os_imp_time(ap_os_imp_time_t **ostime, ap_time_t *aprtime)
{
- if (cont == NULL) {
- return APR_ENOCONT;
- }
- if (thetime == NULL) {
- (*thetime) = (struct atime_t *)ap_palloc(cont, sizeof(struct atime_t));
- (*thetime)->cntxt = cont;
- }
- (*thetime)->explodedtime = atime;
+ /* TODO: Consider not passing in pointer to ap_time_t (e.g., call by value) */
+ AprTimeToFileTime(*ostime, *aprtime);
+ return APR_SUCCESS;
+}
+
+ap_status_t ap_get_os_exp_time(ap_os_exp_time_t **ostime, ap_exploded_time_t *aprexptime)
+{
+ (*ostime)->wYear = aprexptime->tm_year + 1900;
+ (*ostime)->wMonth = aprexptime->tm_mon + 1;
+ (*ostime)->wDayOfWeek = aprexptime->tm_wday;
+ (*ostime)->wDay = aprexptime->tm_mday;
+ (*ostime)->wHour = aprexptime->tm_hour;
+ (*ostime)->wMinute = aprexptime->tm_min;
+ (*ostime)->wSecond = aprexptime->tm_sec;
+ (*ostime)->wMilliseconds = aprexptime->tm_usec / 1000;
+ return APR_SUCCESS;
+}
+
+ap_status_t ap_put_os_imp_time(ap_time_t *aprtime, ap_os_imp_time_t **ostime,
+ ap_context_t *cont)
+{
+ FileTimeToAprTime(aprtime, *ostime);
return APR_SUCCESS;
}
-ap_status_t ap_timediff(struct atime_t *a, struct atime_t *b, ap_int32_t *rv)
+ap_status_t ap_put_os_exp_time(ap_exploded_time_t *aprtime,
+ ap_os_exp_time_t **ostime, ap_context_t *cont)
{
- FILETIME fa, fb;
- LONGLONG ia = 0, ib = 0;
-
- SystemTimeToFileTime(a->explodedtime, &fa);
- SystemTimeToFileTime(b->explodedtime, &fb);
-
- ia = fa.dwHighDateTime;
- ia = ia << 32;
- ia |= fa.dwLowDateTime;
-
- ib = fb.dwHighDateTime;
- ib = ib << 32;
- ib |= fb.dwLowDateTime;
-
- *rv = (int)((ia - ib) / 10000);
+ SystemTimeToAprExpTime(aprtime, *ostime);
return APR_SUCCESS;
}
+