Implementation of SystemTimeToTzSpecificLocalTime() and TzSpecificLocalTimeToSystemTime()
Martin Fuchs
martin-fuchs at gmx.net
Thu Nov 21 17:23:01 CST 2002
ChangeLog
Implementation of SystemTimeToTzSpecificLocalTime() and
TzSpecificLocalTimeToSystemTime()
Index: dlls/kernel/kernel32.spec
===================================================================
RCS file: /home/wine/wine/dlls/kernel/kernel32.spec,v
retrieving revision 1.74
diff -u -r1.74 kernel32.spec
--- dlls/kernel/kernel32.spec 21 Nov 2002 00:02:10 -0000 1.74
+++ dlls/kernel/kernel32.spec 21 Nov 2002 23:04:46 -0000
@@ -727,6 +727,7 @@
@ stdcall SuspendThread(long) SuspendThread
@ stdcall SystemTimeToFileTime(ptr ptr) SystemTimeToFileTime
@ stdcall SystemTimeToTzSpecificLocalTime (ptr ptr ptr)
SystemTimeToTzSpecificLocalTime
+@ stdcall TzSpecificLocalTimeToSystemTime (ptr ptr ptr)
SystemTimeToTzSpecificLocalTime
@ stdcall TerminateProcess(long long) TerminateProcess
@ stdcall TerminateThread(long long) TerminateThread
@ stdcall Thread32First(long ptr) Thread32First
Index: dlls/kernel/time.c
===================================================================
RCS file: /home/wine/wine/dlls/kernel/time.c,v
retrieving revision 1.24
diff -u -r1.24 time.c
--- dlls/kernel/time.c 12 Sep 2002 22:07:03 -0000 1.24
+++ dlls/kernel/time.c 21 Nov 2002 23:04:47 -0000
@@ -500,28 +500,282 @@
/***********************************************************************
+ * _DayLightCompareDate
+ *
+ * Compares two dates without looking at the year
+ *
+ * RETURNS
+ *
+ * -1 if date < compareDate
+ * 0 if date == compareDate
+ * 1 if date > compareDate
+ * -2 if an error occures
+ */
+
+static int _DayLightCompareDate(
+ const LPSYSTEMTIME date, /* [in] The date to
compare. */
+ const LPSYSTEMTIME compareDate) /* [in] The daylight
saving begin or end date */
+{
+ int limit_day;
+
+ if (compareDate->wYear != 0)
+ {
+ if (date->wMonth < compareDate->wMonth)
+ return -1; /* We are in a year before the date limit. */
+
+ if (date->wMonth > compareDate->wMonth)
+ return 1; /* We are in a year after the date limit. */
+ }
+
+ if (date->wMonth < compareDate->wMonth)
+ return -1; /* We are in a month before the date limit. */
+
+ if (date->wMonth > compareDate->wMonth)
+ return 1; /* We are in a month after the date limit. */
+
+ if (compareDate->wDayOfWeek <= 6)
+ {
+ SYSTEMTIME tmp;
+ FILETIME tmp_ft;
+
+ /* compareDate->wDay is interpreted as number of the week in the
month. */
+ /* 5 means: the last week in the month */
+ int weekofmonth = compareDate->wDay;
+
+ /* calculate day of week for the first day in the month */
+ memcpy(&tmp, date, sizeof(SYSTEMTIME));
+ tmp.wDay = 1;
+ tmp.wDayOfWeek = -1;
+
+ if (weekofmonth == 5)
+ {
+ /* Go to the beginning of the next month. */
+ if (++tmp.wMonth > 12)
+ {
+ tmp.wMonth = 1;
+ ++tmp.wYear;
+ }
+ }
+
+ if (!SystemTimeToFileTime(&tmp, &tmp_ft))
+ return -2;
+
+ if (weekofmonth == 5)
+ {
+ long long int t, one_day;
+
+ t = tmp_ft.dwHighDateTime;
+ t <<= 32;
+ t += (UINT)tmp_ft.dwLowDateTime;
+
+ /* substract one day */
+ one_day = 24*60*60;
+ one_day *= 10000000;
+ t -= one_day;
+
+ tmp_ft.dwLowDateTime = (UINT)t;
+ tmp_ft.dwHighDateTime = (UINT)(t >> 32);
+ }
+
+ if (!FileTimeToSystemTime(&tmp_ft, &tmp))
+ return -2;
+
+ if (weekofmonth == 5)
+ {
+ /* calculate the last matching day of the week in this month */
+ int dif = tmp.wDayOfWeek - compareDate->wDayOfWeek;
+ if (dif < 0)
+ dif += 7;
+
+ limit_day = tmp.wDay - dif;
+ }
+ else
+ {
+ /* calulcate the matching day of the week in the given week */
+ int dif = compareDate->wDayOfWeek - tmp.wDayOfWeek;
+ if (dif < 0)
+ dif += 7;
+
+ limit_day = tmp.wDay + 7*weekofmonth + dif;
+ }
+ }
+ else
+ {
+ limit_day = compareDate->wDay;
+ }
+
+ if (date->wDay < limit_day)
+ return -1;
+
+ if (date->wDay > limit_day)
+ return 1;
+
+ return 0; /* date is equal to the date limit. */
+}
+
+
+/***********************************************************************
+ * _GetTimezoneBias
+ *
+ * Calculates the local time bias for a given time zone
+ *
+ * RETURNS
+ *
+ * Returns TRUE when the time zone bias was calculated.
+ */
+
+static BOOL _GetTimezoneBias(
+ const LPTIME_ZONE_INFORMATION lpTimeZoneInformation, /* [in] The time
zone data. */
+ LPSYSTEMTIME lpSystemTime, /* [in] The system
time. */
+ LONG* pBias) /* [out] The
calulated bias in minutes */
+{
+ int ret;
+ BOOL beforedaylightsaving, afterdaylightsaving;
+ BOOL daylightsaving = FALSE;
+ LONG bias = lpTimeZoneInformation->Bias;
+
+ if (lpTimeZoneInformation->DaylightDate.wMonth != 0)
+ {
+ if (lpTimeZoneInformation->StandardDate.wMonth == 0 ||
+ lpTimeZoneInformation->StandardDate.wDay<1 ||
+ lpTimeZoneInformation->StandardDate.wDay>5 ||
+ lpTimeZoneInformation->DaylightDate.wDay<1 ||
+ lpTimeZoneInformation->DaylightDate.wDay>5)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ /* check for daylight saving */
+ ret = _DayLightCompareDate(lpSystemTime,
&lpTimeZoneInformation->StandardDate);
+ if (ret == -2)
+ return -1;
+
+ beforedaylightsaving = ret < 0;
+
+ _DayLightCompareDate(lpSystemTime,
&lpTimeZoneInformation->DaylightDate);
+ if (ret == -2)
+ return -1;
+
+ afterdaylightsaving = ret >= 0;
+
+ if (!beforedaylightsaving && !afterdaylightsaving)
+ daylightsaving = TRUE;
+ }
+
+ if (daylightsaving)
+ bias += lpTimeZoneInformation->DaylightBias;
+ else if (lpTimeZoneInformation->StandardDate.wMonth != 0)
+ bias += lpTimeZoneInformation->StandardBias;
+
+ *pBias = bias;
+
+ return TRUE;
+}
+
+
+/***********************************************************************
* SystemTimeToTzSpecificLocalTime (KERNEL32.@)
*
* Converts the system time (utc) to the local time in the specified time
zone.
*
* RETURNS
*
- * Returns true when the local time was calculated.
+ * Returns TRUE when the local time was calculated.
*
*/
+
BOOL WINAPI SystemTimeToTzSpecificLocalTime(
LPTIME_ZONE_INFORMATION lpTimeZoneInformation, /* [in] The desired time
zone. */
LPSYSTEMTIME lpUniversalTime, /* [in] The utc time to
base local time on. */
LPSYSTEMTIME lpLocalTime) /* [out] The local time in
the time zone. */
{
- FIXME(":stub\n");
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
+ FILETIME ft;
+ LONG lBias;
+ long long int t, bias;
+ TIME_ZONE_INFORMATION tzinfo;
+
+ if (lpTimeZoneInformation != NULL)
+ {
+ memcpy(&tzinfo, lpTimeZoneInformation,
sizeof(TIME_ZONE_INFORMATION));
+ }
+ else
+ {
+ if (GetTimeZoneInformation(&tzinfo) == TIME_ZONE_ID_INVALID)
+ return FALSE;
+ }
+
+ if (!SystemTimeToFileTime(lpUniversalTime, &ft))
+ return FALSE;
+
+ t = ft.dwHighDateTime;
+ t <<= 32;
+ t += (UINT)ft.dwLowDateTime;
+
+ if (!_GetTimezoneBias(&tzinfo, lpUniversalTime, &lBias))
+ return FALSE;
+
+ bias = lBias * 600000000; /* 60 seconds per minute, 100000
[100-nanoseconds-ticks] per second */
+ t += bias;
+
+ ft.dwLowDateTime = (UINT)t;
+ ft.dwHighDateTime = (UINT)(t >> 32);
+
+ return FileTimeToSystemTime(&ft, lpLocalTime);
}
+
+/***********************************************************************
+ * TzSpecificLocalTimeToSystemTime (KERNEL32.@)
+ *
+ * Converts a local time to a time in Coordinated Universal Time (UTC).
+ *
+ * RETURNS
+ *
+ * Returns TRUE when the utc time was calculated.
+ */
+
+BOOL WINAPI TzSpecificLocalTimeToSystemTime(
+ LPTIME_ZONE_INFORMATION lpTimeZoneInformation, /* [in] The desired time
zone. */
+ LPSYSTEMTIME lpLocalTime, /* [in] The local time. */
+ LPSYSTEMTIME lpUniversalTime) /* [out] The calculated
utc time. */
+{
+ FILETIME ft;
+ LONG lBias;
+ long long int t, bias;
+ TIME_ZONE_INFORMATION tzinfo;
+
+ if (lpTimeZoneInformation != NULL)
+ {
+ memcpy(&tzinfo, lpTimeZoneInformation,
sizeof(TIME_ZONE_INFORMATION));
+ }
+ else
+ {
+ if (GetTimeZoneInformation(&tzinfo) == TIME_ZONE_ID_INVALID)
+ return FALSE;
+ }
+
+ if (!SystemTimeToFileTime(lpLocalTime, &ft))
+ return FALSE;
+
+ t = ft.dwHighDateTime;
+ t <<= 32;
+ t += (UINT)ft.dwLowDateTime;
+
+ if (!_GetTimezoneBias(&tzinfo, lpUniversalTime, &lBias))
+ return FALSE;
+
+ bias = lBias * 600000000; /* 60 seconds per minute, 100000
[100-nanoseconds-ticks] per second */
+ t -= bias;
+
+ ft.dwLowDateTime = (UINT)t;
+ ft.dwHighDateTime = (UINT)(t >> 32);
+
+ return FileTimeToSystemTime(&ft, lpUniversalTime);
+}
/***********************************************************************
* GetSystemTimeAsFileTime (KERNEL32.@)
--
Martin Fuchs
martin-fuchs at gmx.net
More information about the wine-patches
mailing list