422049688be94007830a72fb5e0de4dbffc78295
[reactos.git] / lib / kernel32 / misc / time.c
1 /* $Id$
2  *
3  * COPYRIGHT:       See COPYING in the top level directory
4  * PROJECT:         ReactOS system libraries
5  * FILE:            lib/kernel32/misc/time.c
6  * PURPOSE:         Time conversion functions
7  * PROGRAMMER:      Boudewijn ( ariadne@xs4all.nl)
8  *                  DOSDATE and DOSTIME structures from Onno Hovers
9  * UPDATE HISTORY:
10  *                  Created 19/01/99
11  */
12
13 /* INCLUDES ******************************************************************/
14
15 #include <k32.h>
16
17 #define NDEBUG
18 #include <kernel32/kernel32.h>
19
20 /* TYPES *********************************************************************/
21
22 typedef struct __DOSTIME
23 {
24    WORD Second:5;
25    WORD Minute:6;
26    WORD Hour:5;
27 } DOSTIME, *PDOSTIME;
28
29 typedef struct __DOSDATE
30 {
31    WORD Day:5;
32    WORD Month:4;
33    WORD Year:5;
34 } DOSDATE, *PDOSDATE;
35
36 #define TICKSPERMIN        600000000
37
38 /* FUNCTIONS ****************************************************************/
39
40 WINBOOL
41 STDCALL
42 FileTimeToDosDateTime(
43                       CONST FILETIME *lpFileTime,
44                       LPWORD lpFatDate,
45                       LPWORD lpFatTime
46                       )
47 {
48    PDOSTIME  pdtime=(PDOSTIME) lpFatTime;
49    PDOSDATE  pddate=(PDOSDATE) lpFatDate;
50    SYSTEMTIME SystemTime;
51
52    if ( lpFileTime == NULL )
53                 return FALSE;
54
55    if ( lpFatDate == NULL )
56             return FALSE;
57
58    if ( lpFatTime == NULL )
59             return FALSE;
60
61    FileTimeToSystemTime(
62                      lpFileTime,
63                      &SystemTime
64                      );
65
66    pdtime->Second = SystemTime.wSecond;
67    pdtime->Minute = SystemTime.wMinute;
68    pdtime->Hour = SystemTime.wHour;
69
70    pddate->Day = SystemTime.wDay;
71    pddate->Month = SystemTime.wMonth;
72    pddate->Year = SystemTime.wYear - 1980;
73
74    return TRUE; 
75 }
76
77 WINBOOL
78 STDCALL
79 DosDateTimeToFileTime(
80                       WORD wFatDate,
81                       WORD wFatTime,
82                       LPFILETIME lpFileTime
83                       )
84 {
85    PDOSTIME  pdtime = (PDOSTIME) &wFatTime;
86    PDOSDATE  pddate = (PDOSDATE) &wFatDate;
87    SYSTEMTIME SystemTime;
88
89    if ( lpFileTime == NULL )
90                 return FALSE;
91
92    SystemTime.wMilliseconds = 0;
93    SystemTime.wSecond = pdtime->Second;
94    SystemTime.wMinute = pdtime->Minute;
95    SystemTime.wHour = pdtime->Hour;
96
97    SystemTime.wDay = pddate->Day;
98    SystemTime.wMonth = pddate->Month;
99    SystemTime.wYear = 1980 + pddate->Year;
100
101    SystemTimeToFileTime(&SystemTime,lpFileTime);
102    
103    return TRUE;
104 }
105
106 LONG
107 STDCALL
108 CompareFileTime(
109                 CONST FILETIME *lpFileTime1,
110                 CONST FILETIME *lpFileTime2
111                 )
112 {
113   if ( lpFileTime1 == NULL )
114         return 0;
115   if ( lpFileTime2 == NULL )
116         return 0;
117
118   if (*((PLONGLONG)lpFileTime1) > *((PLONGLONG)lpFileTime2))
119         return 1;
120   else if (*((PLONGLONG)lpFileTime1) < *((PLONGLONG)lpFileTime2))
121         return -1;
122
123   return 0;
124 }
125
126 VOID
127 STDCALL 
128 GetSystemTimeAsFileTime(PFILETIME lpFileTime)
129 {
130    NtQuerySystemTime ((TIME *)lpFileTime);
131 }
132
133 WINBOOL 
134 STDCALL
135 SystemTimeToFileTime(
136     CONST SYSTEMTIME *  lpSystemTime,   
137     LPFILETIME  lpFileTime      
138    )
139
140 {
141   TIME_FIELDS TimeFields;
142   LARGE_INTEGER liTime;
143
144   TimeFields.Year = lpSystemTime->wYear;
145   TimeFields.Month = lpSystemTime->wMonth;
146   TimeFields.Day = lpSystemTime->wDay;
147   TimeFields.Hour = lpSystemTime->wHour;
148   TimeFields.Minute = lpSystemTime->wMinute;
149   TimeFields.Second = lpSystemTime->wSecond;
150   TimeFields.Milliseconds = lpSystemTime->wMilliseconds;
151
152   if (RtlTimeFieldsToTime (&TimeFields, &liTime))
153   {
154      lpFileTime->dwLowDateTime = liTime.u.LowPart;
155      lpFileTime->dwHighDateTime = liTime.u.HighPart;
156      return TRUE;
157   }
158   return FALSE;
159 }
160
161 //   dwDayOfWeek = RtlLargeIntegerDivide(FileTime,LIDAY,&dwRemDay);
162 //   lpSystemTime->wDayOfWeek = 1 + GET_LARGE_INTEGER_LOW_PART(dwDayOfWeek) % 7;
163
164   
165
166 WINBOOL
167 STDCALL
168 FileTimeToSystemTime(
169                      CONST FILETIME *lpFileTime,
170                      LPSYSTEMTIME lpSystemTime
171                      )
172 {
173   TIME_FIELDS TimeFields;
174   LARGE_INTEGER liTime;
175
176   if(lpFileTime->dwHighDateTime & 0x80000000)
177    return FALSE;
178
179   liTime.u.LowPart = lpFileTime->dwLowDateTime;
180   liTime.u.HighPart = lpFileTime->dwHighDateTime;
181
182   RtlTimeToTimeFields(&liTime, &TimeFields);
183
184   lpSystemTime->wYear = TimeFields.Year;
185   lpSystemTime->wMonth = TimeFields.Month;
186   lpSystemTime->wDay = TimeFields.Day;
187   lpSystemTime->wHour = TimeFields.Hour;
188   lpSystemTime->wMinute = TimeFields.Minute;
189   lpSystemTime->wSecond = TimeFields.Second;
190   lpSystemTime->wMilliseconds = TimeFields.Milliseconds;
191   lpSystemTime->wDayOfWeek = TimeFields.Weekday;
192
193   return TRUE;
194 }
195
196
197 WINBOOL
198 STDCALL
199 FileTimeToLocalFileTime(
200                         CONST FILETIME *lpFileTime,
201                         LPFILETIME lpLocalFileTime
202                         )
203 {
204   // FIXME: include time bias
205   *((PLONGLONG)lpLocalFileTime) = *((PLONGLONG)lpFileTime);
206
207   return TRUE;
208 }
209
210 WINBOOL
211 STDCALL
212 LocalFileTimeToFileTime(
213                         CONST FILETIME *lpLocalFileTime,
214                         LPFILETIME lpFileTime
215                         )
216 {
217   // FIXME: include time bias
218   *((PLONGLONG)lpFileTime) = *((PLONGLONG)lpLocalFileTime);
219
220   return TRUE;
221 }
222
223
224 VOID STDCALL
225 GetLocalTime(LPSYSTEMTIME lpSystemTime)
226 {
227   FILETIME FileTime;
228   FILETIME LocalFileTime;
229
230   NtQuerySystemTime ((TIME*)&FileTime);
231   FileTimeToLocalFileTime (&FileTime, &LocalFileTime);
232   FileTimeToSystemTime (&LocalFileTime, lpSystemTime);
233 }
234
235
236 VOID STDCALL
237 GetSystemTime(LPSYSTEMTIME lpSystemTime)
238 {
239   FILETIME FileTime;
240
241   NtQuerySystemTime ((TIME*)&FileTime);
242   FileTimeToSystemTime (&FileTime, lpSystemTime);
243 }
244
245
246 WINBOOL STDCALL
247 SetLocalTime(CONST SYSTEMTIME *lpSystemTime)
248 {
249   FILETIME LocalFileTime;
250   LARGE_INTEGER FileTime;
251   NTSTATUS errCode;
252
253   SystemTimeToFileTime (lpSystemTime, &LocalFileTime);
254   LocalFileTimeToFileTime (&LocalFileTime, (FILETIME *)&FileTime);
255   errCode = NtSetSystemTime (&FileTime, &FileTime);
256   if (!NT_SUCCESS(errCode))
257     return FALSE;
258   return TRUE;
259 }
260
261
262 WINBOOL STDCALL
263 SetSystemTime(CONST SYSTEMTIME *lpSystemTime)
264 {
265   LARGE_INTEGER NewSystemTime;
266   NTSTATUS errCode;
267
268   SystemTimeToFileTime (lpSystemTime, (PFILETIME)&NewSystemTime);
269   errCode = NtSetSystemTime (&NewSystemTime, &NewSystemTime);
270   if (!NT_SUCCESS(errCode))
271     return FALSE;
272   return TRUE;
273 }
274
275
276 DWORD STDCALL
277 GetTimeZoneInformation(LPTIME_ZONE_INFORMATION lpTimeZoneInformation)
278 {
279    TIME_ZONE_INFORMATION TimeZoneInformation;
280    NTSTATUS Status;
281
282    DPRINT("GetTimeZoneInformation()\n");
283
284    Status = NtQuerySystemInformation(SystemCurrentTimeZoneInformation,
285                                      &TimeZoneInformation,
286                                      sizeof(TIME_ZONE_INFORMATION),
287                                      NULL);
288    if (!NT_SUCCESS(Status))
289      {
290         SetLastErrorByStatus(Status);
291         return TIME_ZONE_ID_INVALID;
292      }
293
294    memcpy(lpTimeZoneInformation,
295           &TimeZoneInformation,
296           sizeof(TIME_ZONE_INFORMATION));
297
298    return(SharedUserData->TimeZoneId);
299 }
300
301
302 BOOL STDCALL
303 SetTimeZoneInformation(CONST TIME_ZONE_INFORMATION *lpTimeZoneInformation)
304 {
305    TIME_ZONE_INFORMATION TimeZoneInformation;
306    NTSTATUS Status;
307
308    DPRINT("SetTimeZoneInformation()\n");
309
310    memcpy(&TimeZoneInformation,
311           lpTimeZoneInformation,
312           sizeof(TIME_ZONE_INFORMATION));
313
314    Status = RtlSetTimeZoneInformation(&TimeZoneInformation);
315    if (!NT_SUCCESS(Status))
316      {
317         SetLastErrorByStatus(Status);
318         return FALSE;
319      }
320
321    NtSetSystemTime(0,0);
322
323    return TRUE;
324 }
325
326
327 DWORD STDCALL
328 GetCurrentTime(VOID)
329 {
330   return GetTickCount();
331 }
332
333
334 DWORD STDCALL
335 GetTickCount(VOID)
336 {
337   ULONG UpTime;
338   NtGetTickCount(&UpTime);
339   return UpTime;
340 }
341
342
343 WINBOOL STDCALL
344 SystemTimeToTzSpecificLocalTime(
345                                 LPTIME_ZONE_INFORMATION lpTimeZoneInformation,
346                                 LPSYSTEMTIME lpUniversalTime,
347                                 LPSYSTEMTIME lpLocalTime
348                                )
349 {
350   TIME_ZONE_INFORMATION TimeZoneInformation;
351   LPTIME_ZONE_INFORMATION lpTzInfo;
352   LARGE_INTEGER FileTime;
353
354   if (!lpTimeZoneInformation)
355   {
356     GetTimeZoneInformation (&TimeZoneInformation);
357     lpTzInfo = &TimeZoneInformation;
358   }
359   else
360     lpTzInfo = lpTimeZoneInformation;
361
362   if (!lpUniversalTime)
363     return FALSE;
364
365   if (!lpLocalTime)
366     return FALSE;
367
368   SystemTimeToFileTime (lpUniversalTime, (PFILETIME)&FileTime);
369   FileTime.QuadPart -= (lpTzInfo->Bias * TICKSPERMIN);
370   FileTimeToSystemTime ((PFILETIME)&FileTime, lpLocalTime);
371
372   return TRUE;
373 }
374
375
376 WINBOOL STDCALL
377 GetSystemTimeAdjustment(PDWORD lpTimeAdjustment,
378                         PDWORD lpTimeIncrement,
379                         PWINBOOL lpTimeAdjustmentDisabled)
380 {
381    SYSTEM_QUERY_TIME_ADJUSTMENT Buffer;
382    NTSTATUS Status;
383    
384    Status = NtQuerySystemInformation(SystemTimeAdjustmentInformation,
385                                      &Buffer,
386                                      sizeof(SYSTEM_QUERY_TIME_ADJUSTMENT),
387                                      NULL);
388    if (!NT_SUCCESS(Status))
389      {
390         SetLastErrorByStatus(Status);
391         return FALSE;
392      }
393    
394    *lpTimeAdjustment = (DWORD)Buffer.TimeAdjustment;
395    *lpTimeIncrement = (DWORD)Buffer.MaximumIncrement;
396    *lpTimeAdjustmentDisabled = (WINBOOL)Buffer.TimeSynchronization;
397    
398    return TRUE;
399 }
400
401
402 WINBOOL STDCALL
403 SetSystemTimeAdjustment(DWORD dwTimeAdjustment,
404                         WINBOOL bTimeAdjustmentDisabled)
405 {
406    NTSTATUS Status;
407    SYSTEM_TIME_ADJUSTMENT_INFO Buffer;
408    
409    Buffer.TimeAdjustment = (ULONG)dwTimeAdjustment;
410    Buffer.TimeSynchronization = (BOOLEAN)bTimeAdjustmentDisabled;
411    
412    Status = NtSetSystemInformation(SystemTimeAdjustmentInformation,
413                                    &Buffer,
414                                    sizeof(SYSTEM_TIME_ADJUSTMENT_INFO));
415    if (!NT_SUCCESS(Status))
416      {
417         SetLastErrorByStatus(Status);
418         return FALSE;
419      }
420    
421    return TRUE;
422 }
423
424 /* EOF */