90efb5eeb8dbfdfc7afb740a33845d2d78b03aba
[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 /*
41  * @implemented
42  */
43 WINBOOL
44 STDCALL
45 FileTimeToDosDateTime(
46                       CONST FILETIME *lpFileTime,
47                       LPWORD lpFatDate,
48                       LPWORD lpFatTime
49                       )
50 {
51    PDOSTIME  pdtime=(PDOSTIME) lpFatTime;
52    PDOSDATE  pddate=(PDOSDATE) lpFatDate;
53    SYSTEMTIME SystemTime;
54
55    if ( lpFileTime == NULL )
56                 return FALSE;
57
58    if ( lpFatDate == NULL )
59             return FALSE;
60
61    if ( lpFatTime == NULL )
62             return FALSE;
63
64    FileTimeToSystemTime(
65                      lpFileTime,
66                      &SystemTime
67                      );
68
69    pdtime->Second = SystemTime.wSecond;
70    pdtime->Minute = SystemTime.wMinute;
71    pdtime->Hour = SystemTime.wHour;
72
73    pddate->Day = SystemTime.wDay;
74    pddate->Month = SystemTime.wMonth;
75    pddate->Year = SystemTime.wYear - 1980;
76
77    return TRUE; 
78 }
79
80
81 /*
82  * @implemented
83  */
84 WINBOOL
85 STDCALL
86 DosDateTimeToFileTime(
87                       WORD wFatDate,
88                       WORD wFatTime,
89                       LPFILETIME lpFileTime
90                       )
91 {
92    PDOSTIME  pdtime = (PDOSTIME) &wFatTime;
93    PDOSDATE  pddate = (PDOSDATE) &wFatDate;
94    SYSTEMTIME SystemTime;
95
96    if ( lpFileTime == NULL )
97                 return FALSE;
98
99    SystemTime.wMilliseconds = 0;
100    SystemTime.wSecond = pdtime->Second;
101    SystemTime.wMinute = pdtime->Minute;
102    SystemTime.wHour = pdtime->Hour;
103
104    SystemTime.wDay = pddate->Day;
105    SystemTime.wMonth = pddate->Month;
106    SystemTime.wYear = 1980 + pddate->Year;
107
108    SystemTimeToFileTime(&SystemTime,lpFileTime);
109
110    return TRUE;
111 }
112
113
114 /*
115  * @implemented
116  */
117 LONG
118 STDCALL
119 CompareFileTime(
120                 CONST FILETIME *lpFileTime1,
121                 CONST FILETIME *lpFileTime2
122                 )
123 {
124   if ( lpFileTime1 == NULL )
125         return 0;
126   if ( lpFileTime2 == NULL )
127         return 0;
128
129   if (*((PLONGLONG)lpFileTime1) > *((PLONGLONG)lpFileTime2))
130         return 1;
131   else if (*((PLONGLONG)lpFileTime1) < *((PLONGLONG)lpFileTime2))
132         return -1;
133
134   return 0;
135 }
136
137
138 /*
139  * @implemented
140  */
141 VOID STDCALL
142 GetSystemTimeAsFileTime (PFILETIME lpFileTime)
143 {
144   NtQuerySystemTime ((PLARGE_INTEGER)lpFileTime);
145 }
146
147
148 /*
149  * @implemented
150  */
151 WINBOOL 
152 STDCALL
153 SystemTimeToFileTime(
154     CONST SYSTEMTIME *  lpSystemTime,   
155     LPFILETIME  lpFileTime      
156    )
157
158 {
159   TIME_FIELDS TimeFields;
160   LARGE_INTEGER liTime;
161
162   TimeFields.Year = lpSystemTime->wYear;
163   TimeFields.Month = lpSystemTime->wMonth;
164   TimeFields.Day = lpSystemTime->wDay;
165   TimeFields.Hour = lpSystemTime->wHour;
166   TimeFields.Minute = lpSystemTime->wMinute;
167   TimeFields.Second = lpSystemTime->wSecond;
168   TimeFields.Milliseconds = lpSystemTime->wMilliseconds;
169
170   if (RtlTimeFieldsToTime (&TimeFields, &liTime))
171   {
172      lpFileTime->dwLowDateTime = liTime.u.LowPart;
173      lpFileTime->dwHighDateTime = liTime.u.HighPart;
174      return TRUE;
175   }
176   return FALSE;
177 }
178
179
180 /*
181  * @implemented
182  */
183 WINBOOL
184 STDCALL
185 FileTimeToSystemTime(
186                      CONST FILETIME *lpFileTime,
187                      LPSYSTEMTIME lpSystemTime
188                      )
189 {
190   TIME_FIELDS TimeFields;
191   LARGE_INTEGER liTime;
192
193   if(lpFileTime->dwHighDateTime & 0x80000000)
194    return FALSE;
195
196   liTime.u.LowPart = lpFileTime->dwLowDateTime;
197   liTime.u.HighPart = lpFileTime->dwHighDateTime;
198
199   RtlTimeToTimeFields(&liTime, &TimeFields);
200
201   lpSystemTime->wYear = TimeFields.Year;
202   lpSystemTime->wMonth = TimeFields.Month;
203   lpSystemTime->wDay = TimeFields.Day;
204   lpSystemTime->wHour = TimeFields.Hour;
205   lpSystemTime->wMinute = TimeFields.Minute;
206   lpSystemTime->wSecond = TimeFields.Second;
207   lpSystemTime->wMilliseconds = TimeFields.Milliseconds;
208   lpSystemTime->wDayOfWeek = TimeFields.Weekday;
209
210   return TRUE;
211 }
212
213
214 /*
215  * @unimplemented
216  */
217 WINBOOL
218 STDCALL
219 FileTimeToLocalFileTime(
220                         CONST FILETIME *lpFileTime,
221                         LPFILETIME lpLocalFileTime
222                         )
223 {
224   // FIXME: include time bias
225   *((PLONGLONG)lpLocalFileTime) = *((PLONGLONG)lpFileTime);
226
227   return TRUE;
228 }
229
230
231 /*
232  * @unimplemented
233  */
234 WINBOOL
235 STDCALL
236 LocalFileTimeToFileTime(
237                         CONST FILETIME *lpLocalFileTime,
238                         LPFILETIME lpFileTime
239                         )
240 {
241   // FIXME: include time bias
242   *((PLONGLONG)lpFileTime) = *((PLONGLONG)lpLocalFileTime);
243
244   return TRUE;
245 }
246
247
248 /*
249  * @implemented
250  */
251 VOID STDCALL
252 GetLocalTime(LPSYSTEMTIME lpSystemTime)
253 {
254   FILETIME FileTime;
255   FILETIME LocalFileTime;
256
257   NtQuerySystemTime ((PLARGE_INTEGER)&FileTime);
258   FileTimeToLocalFileTime (&FileTime, &LocalFileTime);
259   FileTimeToSystemTime (&LocalFileTime, lpSystemTime);
260 }
261
262
263 /*
264  * @implemented
265  */
266 VOID STDCALL
267 GetSystemTime(LPSYSTEMTIME lpSystemTime)
268 {
269   FILETIME FileTime;
270
271   NtQuerySystemTime ((PLARGE_INTEGER)&FileTime);
272   FileTimeToSystemTime (&FileTime, lpSystemTime);
273 }
274
275
276 /*
277  * @implemented
278  */
279 WINBOOL STDCALL
280 SetLocalTime(CONST SYSTEMTIME *lpSystemTime)
281 {
282   FILETIME LocalFileTime;
283   LARGE_INTEGER FileTime;
284   NTSTATUS errCode;
285
286   SystemTimeToFileTime (lpSystemTime, &LocalFileTime);
287   LocalFileTimeToFileTime (&LocalFileTime, (FILETIME *)&FileTime);
288   errCode = NtSetSystemTime (&FileTime, &FileTime);
289   if (!NT_SUCCESS(errCode))
290     return FALSE;
291   return TRUE;
292 }
293
294
295 /*
296  * @implemented
297  */
298 WINBOOL STDCALL
299 SetSystemTime(CONST SYSTEMTIME *lpSystemTime)
300 {
301   LARGE_INTEGER NewSystemTime;
302   NTSTATUS errCode;
303
304   SystemTimeToFileTime (lpSystemTime, (PFILETIME)&NewSystemTime);
305   errCode = NtSetSystemTime (&NewSystemTime, &NewSystemTime);
306   if (!NT_SUCCESS(errCode))
307     return FALSE;
308   return TRUE;
309 }
310
311
312 /*
313  * @implemented
314  */
315 DWORD STDCALL
316 GetTimeZoneInformation(LPTIME_ZONE_INFORMATION lpTimeZoneInformation)
317 {
318    TIME_ZONE_INFORMATION TimeZoneInformation;
319    NTSTATUS Status;
320
321    DPRINT("GetTimeZoneInformation()\n");
322
323    Status = NtQuerySystemInformation(SystemCurrentTimeZoneInformation,
324                                      &TimeZoneInformation,
325                                      sizeof(TIME_ZONE_INFORMATION),
326                                      NULL);
327    if (!NT_SUCCESS(Status))
328      {
329         SetLastErrorByStatus(Status);
330         return TIME_ZONE_ID_INVALID;
331      }
332
333    memcpy(lpTimeZoneInformation,
334           &TimeZoneInformation,
335           sizeof(TIME_ZONE_INFORMATION));
336
337    return(SharedUserData->TimeZoneId);
338 }
339
340
341 /*
342  * @implemented
343  */
344 BOOL STDCALL
345 SetTimeZoneInformation(CONST TIME_ZONE_INFORMATION *lpTimeZoneInformation)
346 {
347    TIME_ZONE_INFORMATION TimeZoneInformation;
348    NTSTATUS Status;
349
350    DPRINT("SetTimeZoneInformation()\n");
351
352    memcpy(&TimeZoneInformation,
353           lpTimeZoneInformation,
354           sizeof(TIME_ZONE_INFORMATION));
355
356    Status = RtlSetTimeZoneInformation(&TimeZoneInformation);
357    if (!NT_SUCCESS(Status))
358      {
359         SetLastErrorByStatus(Status);
360         return FALSE;
361      }
362
363    NtSetSystemTime(0,0);
364
365    return TRUE;
366 }
367
368
369 /*
370  * @implemented
371  */
372 DWORD STDCALL
373 GetCurrentTime(VOID)
374 {
375   return GetTickCount();
376 }
377
378
379 /*
380  * @implemented
381  */
382 DWORD STDCALL
383 GetTickCount(VOID)
384 {
385   return (DWORD)((ULONGLONG)SharedUserData->TickCountLow * SharedUserData->TickCountMultiplier / 16777216);
386 }
387
388
389 /*
390  * @implemented
391  */
392 WINBOOL STDCALL
393 SystemTimeToTzSpecificLocalTime(
394                                 LPTIME_ZONE_INFORMATION lpTimeZoneInformation,
395                                 LPSYSTEMTIME lpUniversalTime,
396                                 LPSYSTEMTIME lpLocalTime
397                                )
398 {
399   TIME_ZONE_INFORMATION TimeZoneInformation;
400   LPTIME_ZONE_INFORMATION lpTzInfo;
401   LARGE_INTEGER FileTime;
402
403   if (!lpTimeZoneInformation)
404   {
405     GetTimeZoneInformation (&TimeZoneInformation);
406     lpTzInfo = &TimeZoneInformation;
407   }
408   else
409     lpTzInfo = lpTimeZoneInformation;
410
411   if (!lpUniversalTime)
412     return FALSE;
413
414   if (!lpLocalTime)
415     return FALSE;
416
417   SystemTimeToFileTime (lpUniversalTime, (PFILETIME)&FileTime);
418   FileTime.QuadPart -= (lpTzInfo->Bias * TICKSPERMIN);
419   FileTimeToSystemTime ((PFILETIME)&FileTime, lpLocalTime);
420
421   return TRUE;
422 }
423
424
425 /*
426  * @implemented
427  */
428 WINBOOL STDCALL
429 GetSystemTimeAdjustment(PDWORD lpTimeAdjustment,
430                         PDWORD lpTimeIncrement,
431                         PWINBOOL lpTimeAdjustmentDisabled)
432 {
433    SYSTEM_QUERY_TIME_ADJUSTMENT Buffer;
434    NTSTATUS Status;
435    
436    Status = NtQuerySystemInformation(SystemTimeAdjustmentInformation,
437                                      &Buffer,
438                                      sizeof(SYSTEM_QUERY_TIME_ADJUSTMENT),
439                                      NULL);
440    if (!NT_SUCCESS(Status))
441      {
442         SetLastErrorByStatus(Status);
443         return FALSE;
444      }
445    
446    *lpTimeAdjustment = (DWORD)Buffer.TimeAdjustment;
447    *lpTimeIncrement = (DWORD)Buffer.MaximumIncrement;
448    *lpTimeAdjustmentDisabled = (WINBOOL)Buffer.TimeSynchronization;
449    
450    return TRUE;
451 }
452
453
454 /*
455  * @implemented
456  */
457 WINBOOL STDCALL
458 SetSystemTimeAdjustment(DWORD dwTimeAdjustment,
459                         WINBOOL bTimeAdjustmentDisabled)
460 {
461    NTSTATUS Status;
462    SYSTEM_SET_TIME_ADJUSTMENT Buffer;
463    
464    Buffer.TimeAdjustment = (ULONG)dwTimeAdjustment;
465    Buffer.TimeSynchronization = (BOOLEAN)bTimeAdjustmentDisabled;
466    
467    Status = NtSetSystemInformation(SystemTimeAdjustmentInformation,
468                                    &Buffer,
469                                    sizeof(SYSTEM_SET_TIME_ADJUSTMENT));
470    if (!NT_SUCCESS(Status))
471      {
472         SetLastErrorByStatus(Status);
473         return FALSE;
474      }
475    
476    return TRUE;
477 }
478
479 /* EOF */