1c2c66affSColin Finck /*
2c2c66affSColin Finck * COPYRIGHT: See COPYING in the top level directory
3c2c66affSColin Finck * PROJECT: ReactOS system libraries
4c2c66affSColin Finck * FILE: dll/win32/kernel32/wine/timezone.c
5c2c66affSColin Finck * PURPOSE: Time conversion functions
6c2c66affSColin Finck * PROGRAMMER: Ariadne
7c2c66affSColin Finck * DOSDATE and DOSTIME structures from Onno Hovers
8c2c66affSColin Finck * UPDATE HISTORY:
9c2c66affSColin Finck * Created 19/01/99
10c2c66affSColin Finck */
11c2c66affSColin Finck
12c2c66affSColin Finck /* INCLUDES ******************************************************************/
13c2c66affSColin Finck
14c2c66affSColin Finck #include <k32.h>
15c2c66affSColin Finck
16c2c66affSColin Finck #define NDEBUG
17c2c66affSColin Finck #include <debug.h>
18c2c66affSColin Finck
19c2c66affSColin Finck /* TYPES *********************************************************************/
20c2c66affSColin Finck
21c2c66affSColin Finck #define TICKSPERMIN 600000000
22c2c66affSColin Finck
23c2c66affSColin Finck #define LL2FILETIME( ll, pft )\
24c2c66affSColin Finck (pft)->dwLowDateTime = (UINT)(ll); \
25c2c66affSColin Finck (pft)->dwHighDateTime = (UINT)((ll) >> 32);
26c2c66affSColin Finck #define FILETIME2LL( pft, ll) \
27c2c66affSColin Finck ll = (((LONGLONG)((pft)->dwHighDateTime))<<32) + (pft)-> dwLowDateTime ;
28c2c66affSColin Finck
29c2c66affSColin Finck static const int MonthLengths[2][12] =
30c2c66affSColin Finck {
31c2c66affSColin Finck { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
32c2c66affSColin Finck { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
33c2c66affSColin Finck };
34c2c66affSColin Finck
35c2c66affSColin Finck /* STATIC FUNCTIONS **********************************************************/
36c2c66affSColin Finck
IsLeapYear(int Year)37c2c66affSColin Finck static inline int IsLeapYear(int Year)
38c2c66affSColin Finck {
39c2c66affSColin Finck return Year % 4 == 0 && (Year % 100 != 0 || Year % 400 == 0) ? 1 : 0;
40c2c66affSColin Finck }
41c2c66affSColin Finck
42c2c66affSColin Finck /***********************************************************************
43c2c66affSColin Finck * TIME_DayLightCompareDate
44c2c66affSColin Finck *
45c2c66affSColin Finck * Compares two dates without looking at the year.
46c2c66affSColin Finck *
47c2c66affSColin Finck * PARAMS
48c2c66affSColin Finck * date [in] The local time to compare.
49c2c66affSColin Finck * compareDate [in] The daylight savings begin or end date.
50c2c66affSColin Finck *
51c2c66affSColin Finck * RETURNS
52c2c66affSColin Finck *
53c2c66affSColin Finck * -1 if date < compareDate
54c2c66affSColin Finck * 0 if date == compareDate
55c2c66affSColin Finck * 1 if date > compareDate
56c2c66affSColin Finck * -2 if an error occurs
57c2c66affSColin Finck */
58c2c66affSColin Finck static int
TIME_DayLightCompareDate(const SYSTEMTIME * date,const SYSTEMTIME * compareDate)59c2c66affSColin Finck TIME_DayLightCompareDate(const SYSTEMTIME *date, const SYSTEMTIME *compareDate)
60c2c66affSColin Finck {
61c2c66affSColin Finck int limit_day, dayinsecs;
62c2c66affSColin Finck
63c2c66affSColin Finck if (date->wMonth < compareDate->wMonth)
64c2c66affSColin Finck return -1; /* We are in a month before the date limit. */
65c2c66affSColin Finck
66c2c66affSColin Finck if (date->wMonth > compareDate->wMonth)
67c2c66affSColin Finck return 1; /* We are in a month after the date limit. */
68c2c66affSColin Finck
69c2c66affSColin Finck /* if year is 0 then date is in day-of-week format, otherwise
70c2c66affSColin Finck * it's absolute date.
71c2c66affSColin Finck */
72c2c66affSColin Finck if (compareDate->wYear == 0)
73c2c66affSColin Finck {
74c2c66affSColin Finck WORD First;
75c2c66affSColin Finck /* compareDate->wDay is interpreted as number of the week in the month
76c2c66affSColin Finck * 5 means: the last week in the month */
77c2c66affSColin Finck int weekofmonth = compareDate->wDay;
78c2c66affSColin Finck /* calculate the day of the first DayOfWeek in the month */
79c2c66affSColin Finck First = ( 6 + compareDate->wDayOfWeek - date->wDayOfWeek + date->wDay
80c2c66affSColin Finck ) % 7 + 1;
81c2c66affSColin Finck limit_day = First + 7 * (weekofmonth - 1);
82c2c66affSColin Finck /* check needed for the 5th weekday of the month */
83c2c66affSColin Finck if(limit_day > MonthLengths[date->wMonth==2 && IsLeapYear(date->wYear)]
84c2c66affSColin Finck [date->wMonth - 1])
85c2c66affSColin Finck limit_day -= 7;
86c2c66affSColin Finck }
87c2c66affSColin Finck else
88c2c66affSColin Finck {
89c2c66affSColin Finck limit_day = compareDate->wDay;
90c2c66affSColin Finck }
91c2c66affSColin Finck
92c2c66affSColin Finck /* convert to seconds */
93c2c66affSColin Finck limit_day = ((limit_day * 24 + compareDate->wHour) * 60 +
94c2c66affSColin Finck compareDate->wMinute ) * 60;
95c2c66affSColin Finck dayinsecs = ((date->wDay * 24 + date->wHour) * 60 +
96c2c66affSColin Finck date->wMinute ) * 60 + date->wSecond;
97c2c66affSColin Finck /* and compare */
98c2c66affSColin Finck return dayinsecs < limit_day ? -1 :
99c2c66affSColin Finck dayinsecs > limit_day ? 1 :
100c2c66affSColin Finck 0; /* date is equal to the date limit. */
101c2c66affSColin Finck }
102c2c66affSColin Finck
103c2c66affSColin Finck /***********************************************************************
104c2c66affSColin Finck * TIME_CompTimeZoneID
105c2c66affSColin Finck *
106c2c66affSColin Finck * Computes the local time bias for a given time and time zone.
107c2c66affSColin Finck *
108c2c66affSColin Finck * PARAMS
109c2c66affSColin Finck * pTZinfo [in] The time zone data.
110c2c66affSColin Finck * lpFileTime [in] The system or local time.
111c2c66affSColin Finck * islocal [in] it is local time.
112c2c66affSColin Finck *
113c2c66affSColin Finck * RETURNS
114c2c66affSColin Finck * TIME_ZONE_ID_INVALID An error occurred
115c2c66affSColin Finck * TIME_ZONE_ID_UNKNOWN There are no transition time known
116c2c66affSColin Finck * TIME_ZONE_ID_STANDARD Current time is standard time
117c2c66affSColin Finck * TIME_ZONE_ID_DAYLIGHT Current time is daylight savings time
118c2c66affSColin Finck */
119c2c66affSColin Finck static
120c2c66affSColin Finck DWORD
TIME_CompTimeZoneID(const TIME_ZONE_INFORMATION * pTZinfo,FILETIME * lpFileTime,BOOL islocal)121c2c66affSColin Finck TIME_CompTimeZoneID( const TIME_ZONE_INFORMATION *pTZinfo, FILETIME *lpFileTime, BOOL islocal )
122c2c66affSColin Finck {
123c2c66affSColin Finck int ret, year;
124c2c66affSColin Finck BOOL beforeStandardDate, afterDaylightDate;
125c2c66affSColin Finck DWORD retval = TIME_ZONE_ID_INVALID;
126c2c66affSColin Finck LONGLONG llTime = 0; /* initialized to prevent gcc complaining */
127c2c66affSColin Finck SYSTEMTIME SysTime;
128c2c66affSColin Finck FILETIME ftTemp;
129c2c66affSColin Finck
130c2c66affSColin Finck if (pTZinfo->DaylightDate.wMonth != 0)
131c2c66affSColin Finck {
132c2c66affSColin Finck /* if year is 0 then date is in day-of-week format, otherwise
133c2c66affSColin Finck * it's absolute date.
134c2c66affSColin Finck */
135c2c66affSColin Finck if (pTZinfo->StandardDate.wMonth == 0 ||
136c2c66affSColin Finck (pTZinfo->StandardDate.wYear == 0 &&
137c2c66affSColin Finck (pTZinfo->StandardDate.wDay<1 ||
138c2c66affSColin Finck pTZinfo->StandardDate.wDay>5 ||
139c2c66affSColin Finck pTZinfo->DaylightDate.wDay<1 ||
140c2c66affSColin Finck pTZinfo->DaylightDate.wDay>5)))
141c2c66affSColin Finck {
142c2c66affSColin Finck SetLastError(ERROR_INVALID_PARAMETER);
143c2c66affSColin Finck return TIME_ZONE_ID_INVALID;
144c2c66affSColin Finck }
145c2c66affSColin Finck
146c2c66affSColin Finck if (!islocal) {
147c2c66affSColin Finck FILETIME2LL( lpFileTime, llTime );
148c2c66affSColin Finck llTime -= pTZinfo->Bias * (LONGLONG)TICKSPERMIN;
149c2c66affSColin Finck LL2FILETIME( llTime, &ftTemp)
150c2c66affSColin Finck lpFileTime = &ftTemp;
151c2c66affSColin Finck }
152c2c66affSColin Finck
153c2c66affSColin Finck FileTimeToSystemTime(lpFileTime, &SysTime);
154c2c66affSColin Finck year = SysTime.wYear;
155c2c66affSColin Finck
156c2c66affSColin Finck if (!islocal) {
157c2c66affSColin Finck llTime -= pTZinfo->DaylightBias * (LONGLONG)TICKSPERMIN;
158c2c66affSColin Finck LL2FILETIME( llTime, &ftTemp)
159c2c66affSColin Finck FileTimeToSystemTime(lpFileTime, &SysTime);
160c2c66affSColin Finck }
161c2c66affSColin Finck
162c2c66affSColin Finck /* check for daylight savings */
163c2c66affSColin Finck if(year == SysTime.wYear) {
164c2c66affSColin Finck ret = TIME_DayLightCompareDate( &SysTime, &pTZinfo->StandardDate);
165c2c66affSColin Finck if (ret == -2)
166c2c66affSColin Finck return TIME_ZONE_ID_INVALID;
167c2c66affSColin Finck
168c2c66affSColin Finck beforeStandardDate = ret < 0;
169c2c66affSColin Finck } else
170c2c66affSColin Finck beforeStandardDate = SysTime.wYear < year;
171c2c66affSColin Finck
172c2c66affSColin Finck if (!islocal) {
173c2c66affSColin Finck llTime -= ( pTZinfo->StandardBias - pTZinfo->DaylightBias )
174c2c66affSColin Finck * (LONGLONG)TICKSPERMIN;
175c2c66affSColin Finck LL2FILETIME( llTime, &ftTemp)
176c2c66affSColin Finck FileTimeToSystemTime(lpFileTime, &SysTime);
177c2c66affSColin Finck }
178c2c66affSColin Finck
179c2c66affSColin Finck if(year == SysTime.wYear) {
180c2c66affSColin Finck ret = TIME_DayLightCompareDate( &SysTime, &pTZinfo->DaylightDate);
181c2c66affSColin Finck if (ret == -2)
182c2c66affSColin Finck return TIME_ZONE_ID_INVALID;
183c2c66affSColin Finck
184c2c66affSColin Finck afterDaylightDate = ret >= 0;
185c2c66affSColin Finck } else
186c2c66affSColin Finck afterDaylightDate = SysTime.wYear > year;
187c2c66affSColin Finck
188c2c66affSColin Finck retval = TIME_ZONE_ID_STANDARD;
189c2c66affSColin Finck if( pTZinfo->DaylightDate.wMonth < pTZinfo->StandardDate.wMonth ) {
190c2c66affSColin Finck /* Northern hemisphere */
191c2c66affSColin Finck if( beforeStandardDate && afterDaylightDate )
192c2c66affSColin Finck retval = TIME_ZONE_ID_DAYLIGHT;
193c2c66affSColin Finck } else /* Down south */
194c2c66affSColin Finck if( beforeStandardDate || afterDaylightDate )
195c2c66affSColin Finck retval = TIME_ZONE_ID_DAYLIGHT;
196c2c66affSColin Finck } else
197c2c66affSColin Finck /* No transition date */
198c2c66affSColin Finck retval = TIME_ZONE_ID_UNKNOWN;
199c2c66affSColin Finck
200c2c66affSColin Finck return retval;
201c2c66affSColin Finck }
202c2c66affSColin Finck
203c2c66affSColin Finck /***********************************************************************
204c2c66affSColin Finck * TIME_TimeZoneID
205c2c66affSColin Finck *
206c2c66affSColin Finck * Calculates whether daylight savings is on now.
207c2c66affSColin Finck *
208c2c66affSColin Finck * PARAMS
209c2c66affSColin Finck * pTzi [in] Timezone info.
210c2c66affSColin Finck *
211c2c66affSColin Finck * RETURNS
212c2c66affSColin Finck * TIME_ZONE_ID_INVALID An error occurred
213c2c66affSColin Finck * TIME_ZONE_ID_UNKNOWN There are no transition time known
214c2c66affSColin Finck * TIME_ZONE_ID_STANDARD Current time is standard time
215c2c66affSColin Finck * TIME_ZONE_ID_DAYLIGHT Current time is daylight savings time
216c2c66affSColin Finck */
TIME_ZoneID(const TIME_ZONE_INFORMATION * pTzi)217c2c66affSColin Finck static DWORD TIME_ZoneID( const TIME_ZONE_INFORMATION *pTzi )
218c2c66affSColin Finck {
219c2c66affSColin Finck FILETIME ftTime;
220c2c66affSColin Finck GetSystemTimeAsFileTime( &ftTime);
221c2c66affSColin Finck return TIME_CompTimeZoneID( pTzi, &ftTime, FALSE);
222c2c66affSColin Finck }
223c2c66affSColin Finck
224c2c66affSColin Finck /***********************************************************************
225c2c66affSColin Finck * TIME_GetTimezoneBias
226c2c66affSColin Finck *
227c2c66affSColin Finck * Calculates the local time bias for a given time zone.
228c2c66affSColin Finck *
229c2c66affSColin Finck * PARAMS
230c2c66affSColin Finck * pTZinfo [in] The time zone data.
231c2c66affSColin Finck * lpFileTime [in] The system or local time.
232c2c66affSColin Finck * islocal [in] It is local time.
233c2c66affSColin Finck * pBias [out] The calculated bias in minutes.
234c2c66affSColin Finck *
235c2c66affSColin Finck * RETURNS
236c2c66affSColin Finck * TRUE when the time zone bias was calculated.
237c2c66affSColin Finck */
238c2c66affSColin Finck static BOOL
TIME_GetTimezoneBias(const TIME_ZONE_INFORMATION * pTZinfo,FILETIME * lpFileTime,BOOL islocal,LONG * pBias)239c2c66affSColin Finck TIME_GetTimezoneBias(const TIME_ZONE_INFORMATION *pTZinfo, FILETIME *lpFileTime, BOOL islocal, LONG *pBias)
240c2c66affSColin Finck {
241c2c66affSColin Finck LONG bias = pTZinfo->Bias;
242c2c66affSColin Finck DWORD tzid = TIME_CompTimeZoneID(pTZinfo, lpFileTime, islocal);
243c2c66affSColin Finck
244c2c66affSColin Finck if( tzid == TIME_ZONE_ID_INVALID)
245c2c66affSColin Finck return FALSE;
246c2c66affSColin Finck if (tzid == TIME_ZONE_ID_DAYLIGHT)
247c2c66affSColin Finck bias += pTZinfo->DaylightBias;
248c2c66affSColin Finck else if (tzid == TIME_ZONE_ID_STANDARD)
249c2c66affSColin Finck bias += pTZinfo->StandardBias;
250c2c66affSColin Finck *pBias = bias;
251c2c66affSColin Finck return TRUE;
252c2c66affSColin Finck }
253c2c66affSColin Finck
254c2c66affSColin Finck
255c2c66affSColin Finck /* FUNCTIONS ****************************************************************/
256c2c66affSColin Finck
257c2c66affSColin Finck /*
258c2c66affSColin Finck * @implemented
259c2c66affSColin Finck */
260c2c66affSColin Finck DWORD
261c2c66affSColin Finck WINAPI
GetTimeZoneInformation(LPTIME_ZONE_INFORMATION lpTimeZoneInformation)262c2c66affSColin Finck GetTimeZoneInformation(LPTIME_ZONE_INFORMATION lpTimeZoneInformation)
263c2c66affSColin Finck {
26449113829SEric Kohl RTL_TIME_ZONE_INFORMATION TimeZoneInformation;
265c2c66affSColin Finck NTSTATUS Status;
266c2c66affSColin Finck
267c2c66affSColin Finck DPRINT("GetTimeZoneInformation()\n");
268c2c66affSColin Finck
269c2c66affSColin Finck Status = NtQuerySystemInformation(SystemCurrentTimeZoneInformation,
27049113829SEric Kohl &TimeZoneInformation,
27149113829SEric Kohl sizeof(RTL_TIME_ZONE_INFORMATION),
272c2c66affSColin Finck NULL);
273c2c66affSColin Finck if (!NT_SUCCESS(Status))
274c2c66affSColin Finck {
275c2c66affSColin Finck BaseSetLastNTError(Status);
276c2c66affSColin Finck return TIME_ZONE_ID_INVALID;
277c2c66affSColin Finck }
278c2c66affSColin Finck
27949113829SEric Kohl lpTimeZoneInformation->Bias = TimeZoneInformation.Bias;
28049113829SEric Kohl
28149113829SEric Kohl wcsncpy(lpTimeZoneInformation->StandardName,
28249113829SEric Kohl TimeZoneInformation.StandardName,
28349113829SEric Kohl ARRAYSIZE(lpTimeZoneInformation->StandardName));
28449113829SEric Kohl lpTimeZoneInformation->StandardDate.wYear = TimeZoneInformation.StandardDate.Year;
28549113829SEric Kohl lpTimeZoneInformation->StandardDate.wMonth = TimeZoneInformation.StandardDate.Month;
28649113829SEric Kohl lpTimeZoneInformation->StandardDate.wDay = TimeZoneInformation.StandardDate.Day;
28749113829SEric Kohl lpTimeZoneInformation->StandardDate.wHour = TimeZoneInformation.StandardDate.Hour;
28849113829SEric Kohl lpTimeZoneInformation->StandardDate.wMinute = TimeZoneInformation.StandardDate.Minute;
28949113829SEric Kohl lpTimeZoneInformation->StandardDate.wSecond = TimeZoneInformation.StandardDate.Second;
290*bd2f3d39SEric Kohl lpTimeZoneInformation->StandardDate.wMilliseconds = TimeZoneInformation.StandardDate.Milliseconds;
29149113829SEric Kohl lpTimeZoneInformation->StandardDate.wDayOfWeek = TimeZoneInformation.StandardDate.Weekday;
29249113829SEric Kohl lpTimeZoneInformation->StandardBias = TimeZoneInformation.StandardBias;
29349113829SEric Kohl
29449113829SEric Kohl wcsncpy(lpTimeZoneInformation->DaylightName,
29549113829SEric Kohl TimeZoneInformation.DaylightName,
29649113829SEric Kohl ARRAYSIZE(lpTimeZoneInformation->DaylightName));
29749113829SEric Kohl lpTimeZoneInformation->DaylightDate.wYear = TimeZoneInformation.DaylightDate.Year;
29849113829SEric Kohl lpTimeZoneInformation->DaylightDate.wMonth = TimeZoneInformation.DaylightDate.Month;
29949113829SEric Kohl lpTimeZoneInformation->DaylightDate.wDay = TimeZoneInformation.DaylightDate.Day;
30049113829SEric Kohl lpTimeZoneInformation->DaylightDate.wHour = TimeZoneInformation.DaylightDate.Hour;
30149113829SEric Kohl lpTimeZoneInformation->DaylightDate.wMinute = TimeZoneInformation.DaylightDate.Minute;
30249113829SEric Kohl lpTimeZoneInformation->DaylightDate.wSecond = TimeZoneInformation.DaylightDate.Second;
303*bd2f3d39SEric Kohl lpTimeZoneInformation->DaylightDate.wMilliseconds = TimeZoneInformation.DaylightDate.Milliseconds;
30449113829SEric Kohl lpTimeZoneInformation->DaylightDate.wDayOfWeek = TimeZoneInformation.DaylightDate.Weekday;
30549113829SEric Kohl lpTimeZoneInformation->DaylightBias = TimeZoneInformation.DaylightBias;
30649113829SEric Kohl
307c2c66affSColin Finck return TIME_ZoneID(lpTimeZoneInformation);
308c2c66affSColin Finck }
309c2c66affSColin Finck
310c2c66affSColin Finck
311c2c66affSColin Finck /*
312c2c66affSColin Finck * @implemented
313c2c66affSColin Finck */
314c2c66affSColin Finck BOOL
315c2c66affSColin Finck WINAPI
SetTimeZoneInformation(CONST TIME_ZONE_INFORMATION * lpTimeZoneInformation)316c2c66affSColin Finck SetTimeZoneInformation(CONST TIME_ZONE_INFORMATION *lpTimeZoneInformation)
317c2c66affSColin Finck {
31849113829SEric Kohl RTL_TIME_ZONE_INFORMATION TimeZoneInformation;
319c2c66affSColin Finck NTSTATUS Status;
320c2c66affSColin Finck
321c2c66affSColin Finck DPRINT("SetTimeZoneInformation()\n");
322c2c66affSColin Finck
32349113829SEric Kohl TimeZoneInformation.Bias = lpTimeZoneInformation->Bias;
32449113829SEric Kohl
32549113829SEric Kohl wcsncpy(TimeZoneInformation.StandardName,
32649113829SEric Kohl lpTimeZoneInformation->StandardName,
32749113829SEric Kohl ARRAYSIZE(TimeZoneInformation.StandardName));
32849113829SEric Kohl TimeZoneInformation.StandardDate.Year = lpTimeZoneInformation->StandardDate.wYear;
32949113829SEric Kohl TimeZoneInformation.StandardDate.Month = lpTimeZoneInformation->StandardDate.wMonth;
33049113829SEric Kohl TimeZoneInformation.StandardDate.Day = lpTimeZoneInformation->StandardDate.wDay;
33149113829SEric Kohl TimeZoneInformation.StandardDate.Hour = lpTimeZoneInformation->StandardDate.wHour;
33249113829SEric Kohl TimeZoneInformation.StandardDate.Minute = lpTimeZoneInformation->StandardDate.wMinute;
33349113829SEric Kohl TimeZoneInformation.StandardDate.Second = lpTimeZoneInformation->StandardDate.wSecond;
334*bd2f3d39SEric Kohl TimeZoneInformation.StandardDate.Milliseconds = lpTimeZoneInformation->StandardDate.wMilliseconds;
33549113829SEric Kohl TimeZoneInformation.StandardDate.Weekday = lpTimeZoneInformation->StandardDate.wDayOfWeek;
33649113829SEric Kohl TimeZoneInformation.StandardBias = lpTimeZoneInformation->StandardBias;
33749113829SEric Kohl
33849113829SEric Kohl wcsncpy(TimeZoneInformation.DaylightName,
33949113829SEric Kohl lpTimeZoneInformation->DaylightName,
34049113829SEric Kohl ARRAYSIZE(TimeZoneInformation.DaylightName));
34149113829SEric Kohl TimeZoneInformation.DaylightDate.Year = lpTimeZoneInformation->DaylightDate.wYear;
34249113829SEric Kohl TimeZoneInformation.DaylightDate.Month = lpTimeZoneInformation->DaylightDate.wMonth;
34349113829SEric Kohl TimeZoneInformation.DaylightDate.Day = lpTimeZoneInformation->DaylightDate.wDay;
34449113829SEric Kohl TimeZoneInformation.DaylightDate.Hour = lpTimeZoneInformation->DaylightDate.wHour;
34549113829SEric Kohl TimeZoneInformation.DaylightDate.Minute = lpTimeZoneInformation->DaylightDate.wMinute;
34649113829SEric Kohl TimeZoneInformation.DaylightDate.Second = lpTimeZoneInformation->DaylightDate.wSecond;
347*bd2f3d39SEric Kohl TimeZoneInformation.DaylightDate.Milliseconds = lpTimeZoneInformation->DaylightDate.wMilliseconds;
34849113829SEric Kohl TimeZoneInformation.DaylightDate.Weekday = lpTimeZoneInformation->DaylightDate.wDayOfWeek;
34949113829SEric Kohl TimeZoneInformation.DaylightBias = lpTimeZoneInformation->DaylightBias;
35049113829SEric Kohl
35149113829SEric Kohl Status = RtlSetTimeZoneInformation(&TimeZoneInformation);
352c2c66affSColin Finck if (!NT_SUCCESS(Status))
353c2c66affSColin Finck {
354c2c66affSColin Finck DPRINT1("RtlSetTimeZoneInformation() failed (Status %lx)\n", Status);
355c2c66affSColin Finck BaseSetLastNTError(Status);
356c2c66affSColin Finck return FALSE;
357c2c66affSColin Finck }
358c2c66affSColin Finck
359c2c66affSColin Finck Status = NtSetSystemInformation(SystemCurrentTimeZoneInformation,
36049113829SEric Kohl (PVOID)&TimeZoneInformation,
36149113829SEric Kohl sizeof(RTL_TIME_ZONE_INFORMATION));
362c2c66affSColin Finck if (!NT_SUCCESS(Status))
363c2c66affSColin Finck {
364c2c66affSColin Finck DPRINT1("NtSetSystemInformation() failed (Status %lx)\n", Status);
365c2c66affSColin Finck BaseSetLastNTError(Status);
366c2c66affSColin Finck return FALSE;
367c2c66affSColin Finck }
368c2c66affSColin Finck
369c2c66affSColin Finck return TRUE;
370c2c66affSColin Finck }
371c2c66affSColin Finck
372c2c66affSColin Finck /*
373c2c66affSColin Finck * @implemented
374c2c66affSColin Finck */
375c2c66affSColin Finck BOOL
376c2c66affSColin Finck WINAPI
SystemTimeToTzSpecificLocalTime(CONST TIME_ZONE_INFORMATION * lpTimeZoneInformation,CONST SYSTEMTIME * lpUniversalTime,LPSYSTEMTIME lpLocalTime)377c2c66affSColin Finck SystemTimeToTzSpecificLocalTime(CONST TIME_ZONE_INFORMATION *lpTimeZoneInformation,
378c2c66affSColin Finck CONST SYSTEMTIME *lpUniversalTime,
379c2c66affSColin Finck LPSYSTEMTIME lpLocalTime)
380c2c66affSColin Finck {
381c2c66affSColin Finck TIME_ZONE_INFORMATION TzInfo;
382c2c66affSColin Finck FILETIME FileTime;
383c2c66affSColin Finck LONGLONG llTime;
384c2c66affSColin Finck LONG lBias;
385c2c66affSColin Finck
386c2c66affSColin Finck if (lpTimeZoneInformation != NULL)
387c2c66affSColin Finck {
388c2c66affSColin Finck TzInfo = *lpTimeZoneInformation;
389c2c66affSColin Finck }
390c2c66affSColin Finck else
391c2c66affSColin Finck {
392c2c66affSColin Finck if (GetTimeZoneInformation(&TzInfo) == TIME_ZONE_ID_INVALID)
393c2c66affSColin Finck return FALSE;
394c2c66affSColin Finck }
395c2c66affSColin Finck
396c2c66affSColin Finck if (!lpUniversalTime || !lpLocalTime)
397c2c66affSColin Finck return FALSE;
398c2c66affSColin Finck
399c2c66affSColin Finck if (!SystemTimeToFileTime(lpUniversalTime, &FileTime))
400c2c66affSColin Finck return FALSE;
401c2c66affSColin Finck
402c2c66affSColin Finck FILETIME2LL(&FileTime, llTime)
403c2c66affSColin Finck
404c2c66affSColin Finck if (!TIME_GetTimezoneBias(&TzInfo, &FileTime, FALSE, &lBias))
405c2c66affSColin Finck return FALSE;
406c2c66affSColin Finck
407c2c66affSColin Finck /* convert minutes to 100-nanoseconds-ticks */
408c2c66affSColin Finck llTime -= (LONGLONG)lBias * TICKSPERMIN;
409c2c66affSColin Finck
410c2c66affSColin Finck LL2FILETIME( llTime, &FileTime)
411c2c66affSColin Finck
412c2c66affSColin Finck return FileTimeToSystemTime(&FileTime, lpLocalTime);
413c2c66affSColin Finck }
414c2c66affSColin Finck
415c2c66affSColin Finck
416c2c66affSColin Finck /*
417c2c66affSColin Finck * @implemented (Wine 13 sep 2008)
418c2c66affSColin Finck */
419c2c66affSColin Finck BOOL
420c2c66affSColin Finck WINAPI
TzSpecificLocalTimeToSystemTime(LPTIME_ZONE_INFORMATION lpTimeZoneInformation,LPSYSTEMTIME lpLocalTime,LPSYSTEMTIME lpUniversalTime)421c2c66affSColin Finck TzSpecificLocalTimeToSystemTime(LPTIME_ZONE_INFORMATION lpTimeZoneInformation,
422c2c66affSColin Finck LPSYSTEMTIME lpLocalTime,
423c2c66affSColin Finck LPSYSTEMTIME lpUniversalTime)
424c2c66affSColin Finck {
425c2c66affSColin Finck FILETIME ft;
426c2c66affSColin Finck LONG lBias;
427c2c66affSColin Finck LONGLONG t;
428c2c66affSColin Finck TIME_ZONE_INFORMATION tzinfo;
429c2c66affSColin Finck
430c2c66affSColin Finck if (lpTimeZoneInformation != NULL)
431c2c66affSColin Finck {
432c2c66affSColin Finck tzinfo = *lpTimeZoneInformation;
433c2c66affSColin Finck }
434c2c66affSColin Finck else
435c2c66affSColin Finck {
436c2c66affSColin Finck if (GetTimeZoneInformation(&tzinfo) == TIME_ZONE_ID_INVALID)
437c2c66affSColin Finck return FALSE;
438c2c66affSColin Finck }
439c2c66affSColin Finck
440c2c66affSColin Finck if (!SystemTimeToFileTime(lpLocalTime, &ft))
441c2c66affSColin Finck return FALSE;
442c2c66affSColin Finck FILETIME2LL( &ft, t)
443c2c66affSColin Finck if (!TIME_GetTimezoneBias(&tzinfo, &ft, TRUE, &lBias))
444c2c66affSColin Finck return FALSE;
445c2c66affSColin Finck /* convert minutes to 100-nanoseconds-ticks */
446c2c66affSColin Finck t += (LONGLONG)lBias * TICKSPERMIN;
447c2c66affSColin Finck LL2FILETIME( t, &ft)
448c2c66affSColin Finck return FileTimeToSystemTime(&ft, lpUniversalTime);
449c2c66affSColin Finck }
450c2c66affSColin Finck
451c2c66affSColin Finck /* EOF */
452