2003-07-10 Casper S. Hornstrup <chorns@users.sourceforge.net>
[reactos.git] / reactos / lib / kernel32 / misc / time.c
1 /* $Id: time.c,v 1.22 2003/07/10 18:50:51 chorns Exp $
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
142 STDCALL
143 GetSystemTimeAsFileTime(PFILETIME lpFileTime)
144 {
145 NtQuerySystemTime ((TIME *)lpFileTime);
146 }
147
148
149 /*
150 * @implemented
151 */
152 WINBOOL
153 STDCALL
154 SystemTimeToFileTime(
155 CONST SYSTEMTIME * lpSystemTime,
156 LPFILETIME lpFileTime
157 )
158
159 {
160 TIME_FIELDS TimeFields;
161 LARGE_INTEGER liTime;
162
163 TimeFields.Year = lpSystemTime->wYear;
164 TimeFields.Month = lpSystemTime->wMonth;
165 TimeFields.Day = lpSystemTime->wDay;
166 TimeFields.Hour = lpSystemTime->wHour;
167 TimeFields.Minute = lpSystemTime->wMinute;
168 TimeFields.Second = lpSystemTime->wSecond;
169 TimeFields.Milliseconds = lpSystemTime->wMilliseconds;
170
171 if (RtlTimeFieldsToTime (&TimeFields, &liTime))
172 {
173 lpFileTime->dwLowDateTime = liTime.u.LowPart;
174 lpFileTime->dwHighDateTime = liTime.u.HighPart;
175 return TRUE;
176 }
177 return FALSE;
178 }
179
180
181 /*
182 * @implemented
183 */
184 WINBOOL
185 STDCALL
186 FileTimeToSystemTime(
187 CONST FILETIME *lpFileTime,
188 LPSYSTEMTIME lpSystemTime
189 )
190 {
191 TIME_FIELDS TimeFields;
192 LARGE_INTEGER liTime;
193
194 if(lpFileTime->dwHighDateTime & 0x80000000)
195 return FALSE;
196
197 liTime.u.LowPart = lpFileTime->dwLowDateTime;
198 liTime.u.HighPart = lpFileTime->dwHighDateTime;
199
200 RtlTimeToTimeFields(&liTime, &TimeFields);
201
202 lpSystemTime->wYear = TimeFields.Year;
203 lpSystemTime->wMonth = TimeFields.Month;
204 lpSystemTime->wDay = TimeFields.Day;
205 lpSystemTime->wHour = TimeFields.Hour;
206 lpSystemTime->wMinute = TimeFields.Minute;
207 lpSystemTime->wSecond = TimeFields.Second;
208 lpSystemTime->wMilliseconds = TimeFields.Milliseconds;
209 lpSystemTime->wDayOfWeek = TimeFields.Weekday;
210
211 return TRUE;
212 }
213
214
215 /*
216 * @unimplemented
217 */
218 WINBOOL
219 STDCALL
220 FileTimeToLocalFileTime(
221 CONST FILETIME *lpFileTime,
222 LPFILETIME lpLocalFileTime
223 )
224 {
225 // FIXME: include time bias
226 *((PLONGLONG)lpLocalFileTime) = *((PLONGLONG)lpFileTime);
227
228 return TRUE;
229 }
230
231
232 /*
233 * @unimplemented
234 */
235 WINBOOL
236 STDCALL
237 LocalFileTimeToFileTime(
238 CONST FILETIME *lpLocalFileTime,
239 LPFILETIME lpFileTime
240 )
241 {
242 // FIXME: include time bias
243 *((PLONGLONG)lpFileTime) = *((PLONGLONG)lpLocalFileTime);
244
245 return TRUE;
246 }
247
248
249 /*
250 * @implemented
251 */
252 VOID STDCALL
253 GetLocalTime(LPSYSTEMTIME lpSystemTime)
254 {
255 FILETIME FileTime;
256 FILETIME LocalFileTime;
257
258 NtQuerySystemTime ((TIME*)&FileTime);
259 FileTimeToLocalFileTime (&FileTime, &LocalFileTime);
260 FileTimeToSystemTime (&LocalFileTime, lpSystemTime);
261 }
262
263
264 /*
265 * @implemented
266 */
267 VOID STDCALL
268 GetSystemTime(LPSYSTEMTIME lpSystemTime)
269 {
270 FILETIME FileTime;
271
272 NtQuerySystemTime ((TIME*)&FileTime);
273 FileTimeToSystemTime (&FileTime, lpSystemTime);
274 }
275
276
277 /*
278 * @implemented
279 */
280 WINBOOL STDCALL
281 SetLocalTime(CONST SYSTEMTIME *lpSystemTime)
282 {
283 FILETIME LocalFileTime;
284 LARGE_INTEGER FileTime;
285 NTSTATUS errCode;
286
287 SystemTimeToFileTime (lpSystemTime, &LocalFileTime);
288 LocalFileTimeToFileTime (&LocalFileTime, (FILETIME *)&FileTime);
289 errCode = NtSetSystemTime (&FileTime, &FileTime);
290 if (!NT_SUCCESS(errCode))
291 return FALSE;
292 return TRUE;
293 }
294
295
296 /*
297 * @implemented
298 */
299 WINBOOL STDCALL
300 SetSystemTime(CONST SYSTEMTIME *lpSystemTime)
301 {
302 LARGE_INTEGER NewSystemTime;
303 NTSTATUS errCode;
304
305 SystemTimeToFileTime (lpSystemTime, (PFILETIME)&NewSystemTime);
306 errCode = NtSetSystemTime (&NewSystemTime, &NewSystemTime);
307 if (!NT_SUCCESS(errCode))
308 return FALSE;
309 return TRUE;
310 }
311
312
313 /*
314 * @implemented
315 */
316 DWORD STDCALL
317 GetTimeZoneInformation(LPTIME_ZONE_INFORMATION lpTimeZoneInformation)
318 {
319 TIME_ZONE_INFORMATION TimeZoneInformation;
320 NTSTATUS Status;
321
322 DPRINT("GetTimeZoneInformation()\n");
323
324 Status = NtQuerySystemInformation(SystemCurrentTimeZoneInformation,
325 &TimeZoneInformation,
326 sizeof(TIME_ZONE_INFORMATION),
327 NULL);
328 if (!NT_SUCCESS(Status))
329 {
330 SetLastErrorByStatus(Status);
331 return TIME_ZONE_ID_INVALID;
332 }
333
334 memcpy(lpTimeZoneInformation,
335 &TimeZoneInformation,
336 sizeof(TIME_ZONE_INFORMATION));
337
338 return(SharedUserData->TimeZoneId);
339 }
340
341
342 /*
343 * @implemented
344 */
345 BOOL STDCALL
346 SetTimeZoneInformation(CONST TIME_ZONE_INFORMATION *lpTimeZoneInformation)
347 {
348 TIME_ZONE_INFORMATION TimeZoneInformation;
349 NTSTATUS Status;
350
351 DPRINT("SetTimeZoneInformation()\n");
352
353 memcpy(&TimeZoneInformation,
354 lpTimeZoneInformation,
355 sizeof(TIME_ZONE_INFORMATION));
356
357 Status = RtlSetTimeZoneInformation(&TimeZoneInformation);
358 if (!NT_SUCCESS(Status))
359 {
360 SetLastErrorByStatus(Status);
361 return FALSE;
362 }
363
364 NtSetSystemTime(0,0);
365
366 return TRUE;
367 }
368
369
370 /*
371 * @implemented
372 */
373 DWORD STDCALL
374 GetCurrentTime(VOID)
375 {
376 return GetTickCount();
377 }
378
379
380 /*
381 * @implemented
382 */
383 DWORD STDCALL
384 GetTickCount(VOID)
385 {
386 return (DWORD)((ULONGLONG)SharedUserData->TickCountLow * SharedUserData->TickCountMultiplier / 16777216);
387 }
388
389
390 /*
391 * @implemented
392 */
393 WINBOOL STDCALL
394 SystemTimeToTzSpecificLocalTime(
395 LPTIME_ZONE_INFORMATION lpTimeZoneInformation,
396 LPSYSTEMTIME lpUniversalTime,
397 LPSYSTEMTIME lpLocalTime
398 )
399 {
400 TIME_ZONE_INFORMATION TimeZoneInformation;
401 LPTIME_ZONE_INFORMATION lpTzInfo;
402 LARGE_INTEGER FileTime;
403
404 if (!lpTimeZoneInformation)
405 {
406 GetTimeZoneInformation (&TimeZoneInformation);
407 lpTzInfo = &TimeZoneInformation;
408 }
409 else
410 lpTzInfo = lpTimeZoneInformation;
411
412 if (!lpUniversalTime)
413 return FALSE;
414
415 if (!lpLocalTime)
416 return FALSE;
417
418 SystemTimeToFileTime (lpUniversalTime, (PFILETIME)&FileTime);
419 FileTime.QuadPart -= (lpTzInfo->Bias * TICKSPERMIN);
420 FileTimeToSystemTime ((PFILETIME)&FileTime, lpLocalTime);
421
422 return TRUE;
423 }
424
425
426 /*
427 * @implemented
428 */
429 WINBOOL STDCALL
430 GetSystemTimeAdjustment(PDWORD lpTimeAdjustment,
431 PDWORD lpTimeIncrement,
432 PWINBOOL lpTimeAdjustmentDisabled)
433 {
434 SYSTEM_QUERY_TIME_ADJUSTMENT Buffer;
435 NTSTATUS Status;
436
437 Status = NtQuerySystemInformation(SystemTimeAdjustmentInformation,
438 &Buffer,
439 sizeof(SYSTEM_QUERY_TIME_ADJUSTMENT),
440 NULL);
441 if (!NT_SUCCESS(Status))
442 {
443 SetLastErrorByStatus(Status);
444 return FALSE;
445 }
446
447 *lpTimeAdjustment = (DWORD)Buffer.TimeAdjustment;
448 *lpTimeIncrement = (DWORD)Buffer.MaximumIncrement;
449 *lpTimeAdjustmentDisabled = (WINBOOL)Buffer.TimeSynchronization;
450
451 return TRUE;
452 }
453
454
455 /*
456 * @implemented
457 */
458 WINBOOL STDCALL
459 SetSystemTimeAdjustment(DWORD dwTimeAdjustment,
460 WINBOOL bTimeAdjustmentDisabled)
461 {
462 NTSTATUS Status;
463 SYSTEM_TIME_ADJUSTMENT_INFO Buffer;
464
465 Buffer.TimeAdjustment = (ULONG)dwTimeAdjustment;
466 Buffer.TimeSynchronization = (BOOLEAN)bTimeAdjustmentDisabled;
467
468 Status = NtSetSystemInformation(SystemTimeAdjustmentInformation,
469 &Buffer,
470 sizeof(SYSTEM_TIME_ADJUSTMENT_INFO));
471 if (!NT_SUCCESS(Status))
472 {
473 SetLastErrorByStatus(Status);
474 return FALSE;
475 }
476
477 return TRUE;
478 }
479
480 /* EOF */