[PATCH] msvcrt: Use RtlQueryTimeZoneInformation when MUI not required.
Alistair Leslie-Hughes
leslie_alistair at hotmail.com
Thu Dec 20 16:46:17 CST 2018
TIME_ZoneID copied from dlls/kernel32/time.c
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=46266
Signed-off-by: Alistair Leslie-Hughes <leslie_alistair at hotmail.com>
---
If we dont care about an invalid TIME_ZONE then we have the possiblity
to use GetDaylightFlag to reduce the amount of code.
MSVCRT__ftime64
....
buf->timezone = tzinfo.Bias +
( tzid == TIME_ZONE_ID_STANDARD ? tzinfo.StandardBias :
( tzid == TIME_ZONE_ID_DAYLIGHT ? tzinfo.DaylightBias : 0 ));
dlls/msvcrt/time.c | 144 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 143 insertions(+), 1 deletion(-)
diff --git a/dlls/msvcrt/time.c b/dlls/msvcrt/time.c
index 861b2ed..521c6c8 100644
--- a/dlls/msvcrt/time.c
+++ b/dlls/msvcrt/time.c
@@ -760,6 +760,146 @@ double CDECL MSVCRT_difftime(MSVCRT___time32_t time1, MSVCRT___time32_t time2)
}
#endif
+#define LL2FILETIME( ll, pft )\
+ (pft)->dwLowDateTime = (UINT)(ll); \
+ (pft)->dwHighDateTime = (UINT)((ll) >> 32);
+#define FILETIME2LL( pft, ll) \
+ ll = (((LONGLONG)((pft)->dwHighDateTime))<<32) + (pft)-> dwLowDateTime ;
+
+static int TIME_DayLightCompareDate( const SYSTEMTIME *date,
+ const SYSTEMTIME *compareDate )
+{
+ int limit_day, dayinsecs;
+
+ 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 year is 0 then date is in day-of-week format, otherwise
+ * it's absolute date.
+ */
+ if (compareDate->wYear == 0)
+ {
+ WORD First;
+ /* 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 the day of the first DayOfWeek in the month */
+ First = ( 6 + compareDate->wDayOfWeek - date->wDayOfWeek + date->wDay
+ ) % 7 + 1;
+ limit_day = First + 7 * (weekofmonth - 1);
+ /* check needed for the 5th weekday of the month */
+ if(limit_day > MonthLengths[date->wMonth==2 && IsLeapYear(date->wYear)]
+ [date->wMonth - 1])
+ limit_day -= 7;
+ }
+ else
+ {
+ limit_day = compareDate->wDay;
+ }
+
+ /* convert to seconds */
+ limit_day = ((limit_day * 24 + compareDate->wHour) * 60 +
+ compareDate->wMinute ) * 60;
+ dayinsecs = ((date->wDay * 24 + date->wHour) * 60 +
+ date->wMinute ) * 60 + date->wSecond;
+ /* and compare */
+ return dayinsecs < limit_day ? -1 :
+ dayinsecs > limit_day ? 1 :
+ 0; /* date is equal to the date limit. */
+}
+
+static DWORD TIME_CompTimeZoneID ( const TIME_ZONE_INFORMATION *pTZinfo,
+ FILETIME *lpFileTime, BOOL islocal )
+{
+ int ret, year;
+ BOOL beforeStandardDate, afterDaylightDate;
+ DWORD retval = TIME_ZONE_ID_INVALID;
+ LONGLONG llTime = 0; /* initialized to prevent gcc complaining */
+ SYSTEMTIME SysTime;
+ FILETIME ftTemp;
+
+ if (pTZinfo->DaylightDate.wMonth != 0)
+ {
+ /* if year is 0 then date is in day-of-week format, otherwise
+ * it's absolute date.
+ */
+ if (pTZinfo->StandardDate.wMonth == 0 ||
+ (pTZinfo->StandardDate.wYear == 0 &&
+ (pTZinfo->StandardDate.wDay<1 ||
+ pTZinfo->StandardDate.wDay>5 ||
+ pTZinfo->DaylightDate.wDay<1 ||
+ pTZinfo->DaylightDate.wDay>5)))
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return TIME_ZONE_ID_INVALID;
+ }
+
+ if (!islocal) {
+ FILETIME2LL( lpFileTime, llTime );
+ llTime -= pTZinfo->Bias * (LONGLONG)600000000;
+ LL2FILETIME( llTime, &ftTemp)
+ lpFileTime = &ftTemp;
+ }
+
+ FileTimeToSystemTime(lpFileTime, &SysTime);
+ year = SysTime.wYear;
+
+ if (!islocal) {
+ llTime -= pTZinfo->DaylightBias * (LONGLONG)600000000;
+ LL2FILETIME( llTime, &ftTemp)
+ FileTimeToSystemTime(lpFileTime, &SysTime);
+ }
+
+ if(year == SysTime.wYear) {
+ ret = TIME_DayLightCompareDate( &SysTime, &pTZinfo->StandardDate);
+ if (ret == -2)
+ return TIME_ZONE_ID_INVALID;
+
+ beforeStandardDate = ret < 0;
+ } else
+ beforeStandardDate = SysTime.wYear < year;
+
+ if (!islocal) {
+ llTime -= ( pTZinfo->StandardBias - pTZinfo->DaylightBias )
+ * (LONGLONG)600000000;
+ LL2FILETIME( llTime, &ftTemp)
+ FileTimeToSystemTime(lpFileTime, &SysTime);
+ }
+
+ if(year == SysTime.wYear) {
+ ret = TIME_DayLightCompareDate( &SysTime, &pTZinfo->DaylightDate);
+ if (ret == -2)
+ return TIME_ZONE_ID_INVALID;
+
+ afterDaylightDate = ret >= 0;
+ } else
+ afterDaylightDate = SysTime.wYear > year;
+
+ retval = TIME_ZONE_ID_STANDARD;
+ if( pTZinfo->DaylightDate.wMonth < pTZinfo->StandardDate.wMonth ) {
+ /* Northern hemisphere */
+ if( beforeStandardDate && afterDaylightDate )
+ retval = TIME_ZONE_ID_DAYLIGHT;
+ } else /* Down south */
+ if( beforeStandardDate || afterDaylightDate )
+ retval = TIME_ZONE_ID_DAYLIGHT;
+ } else
+ /* No transition date */
+ retval = TIME_ZONE_ID_UNKNOWN;
+
+ return retval;
+}
+
+
+static DWORD TIME_ZoneID( const TIME_ZONE_INFORMATION *pTzi )
+{
+ FILETIME ftTime;
+ GetSystemTimeAsFileTime( &ftTime);
+ return TIME_CompTimeZoneID( pTzi, &ftTime, FALSE);
+}
/*********************************************************************
* _ftime64 (MSVCRT.@)
*/
@@ -768,8 +908,10 @@ void CDECL MSVCRT__ftime64(struct MSVCRT___timeb64 *buf)
TIME_ZONE_INFORMATION tzinfo;
FILETIME ft;
ULONGLONG time;
+ DWORD tzid;
- DWORD tzid = GetTimeZoneInformation(&tzinfo);
+ RtlQueryTimeZoneInformation((RTL_TIME_ZONE_INFORMATION *)&tzinfo);
+ tzid = TIME_ZoneID(&tzinfo);
GetSystemTimeAsFileTime(&ft);
time = ((ULONGLONG)ft.dwHighDateTime << 32) | ft.dwLowDateTime;
--
1.9.1
More information about the wine-devel
mailing list