2 * Win32 kernel time functions
4 * Copyright 1995 Martin von Loewis and Cameron Heide
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 #ifdef HAVE_SYS_TIME_H
29 # include <sys/time.h>
31 #ifdef HAVE_SYS_TIMES_H
32 # include <sys/times.h>
35 #define NONAMELESSUNION
36 #define NONAMELESSSTRUCT
42 #include "kernel_private.h"
43 #include "wine/unicode.h"
44 #include "wine/debug.h"
46 WINE_DEFAULT_DEBUG_CHANNEL(time);
48 /* maximum time adjustment in seconds for SetLocalTime and SetSystemTime */
49 #define SETTIME_MAX_ADJUST 120
50 #define CALINFO_MAX_YEAR 2029
53 /***********************************************************************
54 * SetLocalTime (KERNEL32.@)
56 * Set the local time using current time zone and daylight
60 * Success: TRUE. The time was set
61 * Failure: FALSE, if the time was invalid or caller does not have
62 * permission to change the time.
64 BOOL WINAPI SetLocalTime(
65 const SYSTEMTIME *systime) /* [in] The desired local time. */
68 LARGE_INTEGER st, st2;
71 SystemTimeToFileTime( systime, &ft );
72 st.u.LowPart = ft.dwLowDateTime;
73 st.u.HighPart = ft.dwHighDateTime;
74 RtlLocalTimeToSystemTime( &st, &st2 );
76 if ((status = NtSetSystemTime(&st2, NULL)))
77 SetLastError( RtlNtStatusToDosError(status) );
82 /***********************************************************************
83 * GetSystemTimeAdjustment (KERNEL32.@)
85 * Get the period between clock interrupts and the amount the clock
86 * is adjusted each interrupt so as to keep it in sync with an external source.
92 * Only the special case of disabled time adjustments is supported.
94 BOOL WINAPI GetSystemTimeAdjustment(
95 PDWORD lpTimeAdjustment, /* [out] The clock adjustment per interupt in 100's of nanoseconds. */
96 PDWORD lpTimeIncrement, /* [out] The time between clock interupts in 100's of nanoseconds. */
97 PBOOL lpTimeAdjustmentDisabled) /* [out] The clock synchonisation has been disabled. */
99 *lpTimeAdjustment = 0;
100 *lpTimeIncrement = 0;
101 *lpTimeAdjustmentDisabled = TRUE;
106 /***********************************************************************
107 * SetSystemTime (KERNEL32.@)
109 * Set the system time in utc.
112 * Success: TRUE. The time was set
113 * Failure: FALSE, if the time was invalid or caller does not have
114 * permission to change the time.
116 BOOL WINAPI SetSystemTime(
117 const SYSTEMTIME *systime) /* [in] The desired system time. */
123 SystemTimeToFileTime( systime, &ft );
124 t.u.LowPart = ft.dwLowDateTime;
125 t.u.HighPart = ft.dwHighDateTime;
126 if ((status = NtSetSystemTime(&t, NULL)))
127 SetLastError( RtlNtStatusToDosError(status) );
131 /***********************************************************************
132 * SetSystemTimeAdjustment (KERNEL32.@)
134 * Enables or disables the timing adjustments to the system's clock.
140 BOOL WINAPI SetSystemTimeAdjustment(
141 DWORD dwTimeAdjustment,
142 BOOL bTimeAdjustmentDisabled)
144 /* Fake function for now... */
145 FIXME("(%08lx,%d): stub !\n", dwTimeAdjustment, bTimeAdjustmentDisabled);
150 /***********************************************************************
151 * GetTimeZoneInformation (KERNEL32.@)
153 * Get information about the current local time zone.
156 * Success: TIME_ZONE_ID_STANDARD. tzinfo contains the time zone info.
157 * Failure: TIME_ZONE_ID_INVALID.
158 * FIXME: return TIME_ZONE_ID_DAYLIGHT when daylight saving is on.
160 DWORD WINAPI GetTimeZoneInformation(
161 LPTIME_ZONE_INFORMATION tzinfo) /* [out] Destination for time zone information */
164 if ((status = RtlQueryTimeZoneInformation(tzinfo)))
165 SetLastError( RtlNtStatusToDosError(status) );
166 return TIME_ZONE_ID_STANDARD;
170 /***********************************************************************
171 * SetTimeZoneInformation (KERNEL32.@)
173 * Change the settings of the current local time zone.
176 * Success: TRUE. The time zone was updated with the settings from tzinfo
179 BOOL WINAPI SetTimeZoneInformation(
180 const LPTIME_ZONE_INFORMATION tzinfo) /* [in] The new time zone. */
183 if ((status = RtlSetTimeZoneInformation(tzinfo)))
184 SetLastError( RtlNtStatusToDosError(status) );
189 /***********************************************************************
190 * _DayLightCompareDate
192 * Compares two dates without looking at the year
196 * -1 if date < compareDate
197 * 0 if date == compareDate
198 * 1 if date > compareDate
199 * -2 if an error occures
202 static int _DayLightCompareDate(
203 const LPSYSTEMTIME date, /* [in] The date to compare. */
204 const LPSYSTEMTIME compareDate) /* [in] The daylight saving begin or end date */
208 if (compareDate->wYear != 0)
210 if (date->wMonth < compareDate->wMonth)
211 return -1; /* We are in a year before the date limit. */
213 if (date->wMonth > compareDate->wMonth)
214 return 1; /* We are in a year after the date limit. */
217 if (date->wMonth < compareDate->wMonth)
218 return -1; /* We are in a month before the date limit. */
220 if (date->wMonth > compareDate->wMonth)
221 return 1; /* We are in a month after the date limit. */
223 if (compareDate->wDayOfWeek <= 6)
228 /* compareDate->wDay is interpreted as number of the week in the month. */
229 /* 5 means: the last week in the month */
230 int weekofmonth = compareDate->wDay;
232 /* calculate day of week for the first day in the month */
233 memcpy(&tmp, date, sizeof(SYSTEMTIME));
237 if (weekofmonth == 5)
239 /* Go to the beginning of the next month. */
240 if (++tmp.wMonth > 12)
247 if (!SystemTimeToFileTime(&tmp, &tmp_ft))
250 if (weekofmonth == 5)
254 t = tmp_ft.dwHighDateTime;
256 t += (UINT)tmp_ft.dwLowDateTime;
258 /* subtract one day */
263 tmp_ft.dwLowDateTime = (UINT)t;
264 tmp_ft.dwHighDateTime = (UINT)(t >> 32);
267 if (!FileTimeToSystemTime(&tmp_ft, &tmp))
270 if (weekofmonth == 5)
272 /* calculate the last matching day of the week in this month */
273 int dif = tmp.wDayOfWeek - compareDate->wDayOfWeek;
277 limit_day = tmp.wDay - dif;
281 /* calculate the matching day of the week in the given week */
282 int dif = compareDate->wDayOfWeek - tmp.wDayOfWeek;
286 limit_day = tmp.wDay + 7*(weekofmonth-1) + dif;
291 limit_day = compareDate->wDay;
294 if (date->wDay < limit_day)
297 if (date->wDay > limit_day)
300 return 0; /* date is equal to the date limit. */
304 /***********************************************************************
307 * Calculates the local time bias for a given time zone
311 * Returns TRUE when the time zone bias was calculated.
314 static BOOL _GetTimezoneBias(
315 const LPTIME_ZONE_INFORMATION lpTimeZoneInformation, /* [in] The time zone data. */
316 LPSYSTEMTIME lpSystemTime, /* [in] The system time. */
317 LONG* pBias) /* [out] The calulated bias in minutes */
320 BOOL beforeStandardDate, afterDaylightDate;
321 BOOL daylightsaving = FALSE;
322 LONG bias = lpTimeZoneInformation->Bias;
324 if (lpTimeZoneInformation->DaylightDate.wMonth != 0)
326 if (lpTimeZoneInformation->StandardDate.wMonth == 0 ||
327 lpTimeZoneInformation->StandardDate.wDay<1 ||
328 lpTimeZoneInformation->StandardDate.wDay>5 ||
329 lpTimeZoneInformation->DaylightDate.wDay<1 ||
330 lpTimeZoneInformation->DaylightDate.wDay>5)
332 SetLastError(ERROR_INVALID_PARAMETER);
336 /* check for daylight saving */
337 ret = _DayLightCompareDate(lpSystemTime, &lpTimeZoneInformation->StandardDate);
341 beforeStandardDate = ret < 0;
343 ret = _DayLightCompareDate(lpSystemTime, &lpTimeZoneInformation->DaylightDate);
347 afterDaylightDate = ret >= 0;
349 if (beforeStandardDate && afterDaylightDate)
350 daylightsaving = TRUE;
354 bias += lpTimeZoneInformation->DaylightBias;
355 else if (lpTimeZoneInformation->StandardDate.wMonth != 0)
356 bias += lpTimeZoneInformation->StandardBias;
364 /***********************************************************************
365 * SystemTimeToTzSpecificLocalTime (KERNEL32.@)
367 * Convert a utc system time to a local time in a given time zone.
370 * Success: TRUE. lpLocalTime contains the converted time
374 BOOL WINAPI SystemTimeToTzSpecificLocalTime(
375 LPTIME_ZONE_INFORMATION lpTimeZoneInformation, /* [in] The desired time zone. */
376 LPSYSTEMTIME lpUniversalTime, /* [in] The utc time to base local time on. */
377 LPSYSTEMTIME lpLocalTime) /* [out] The local time in the time zone. */
382 TIME_ZONE_INFORMATION tzinfo;
384 if (lpTimeZoneInformation != NULL)
386 memcpy(&tzinfo, lpTimeZoneInformation, sizeof(TIME_ZONE_INFORMATION));
390 if (GetTimeZoneInformation(&tzinfo) == TIME_ZONE_ID_INVALID)
394 if (!SystemTimeToFileTime(lpUniversalTime, &ft))
397 t = ft.dwHighDateTime;
399 t += (UINT)ft.dwLowDateTime;
401 if (!_GetTimezoneBias(&tzinfo, lpUniversalTime, &lBias))
404 bias = (LONGLONG)lBias * 600000000; /* 60 seconds per minute, 100000 [100-nanoseconds-ticks] per second */
407 ft.dwLowDateTime = (UINT)t;
408 ft.dwHighDateTime = (UINT)(t >> 32);
410 return FileTimeToSystemTime(&ft, lpLocalTime);
414 /***********************************************************************
415 * TzSpecificLocalTimeToSystemTime (KERNEL32.@)
417 * Converts a local time to a time in utc.
420 * Success: TRUE. lpUniversalTime contains the converted time
423 BOOL WINAPI TzSpecificLocalTimeToSystemTime(
424 LPTIME_ZONE_INFORMATION lpTimeZoneInformation, /* [in] The desired time zone. */
425 LPSYSTEMTIME lpLocalTime, /* [in] The local time. */
426 LPSYSTEMTIME lpUniversalTime) /* [out] The calculated utc time. */
431 TIME_ZONE_INFORMATION tzinfo;
433 if (lpTimeZoneInformation != NULL)
435 memcpy(&tzinfo, lpTimeZoneInformation, sizeof(TIME_ZONE_INFORMATION));
439 if (GetTimeZoneInformation(&tzinfo) == TIME_ZONE_ID_INVALID)
443 if (!SystemTimeToFileTime(lpLocalTime, &ft))
446 t = ft.dwHighDateTime;
448 t += (UINT)ft.dwLowDateTime;
450 if (!_GetTimezoneBias(&tzinfo, lpLocalTime, &lBias))
453 bias = (LONGLONG)lBias * 600000000; /* 60 seconds per minute, 100000 [100-nanoseconds-ticks] per second */
456 ft.dwLowDateTime = (UINT)t;
457 ft.dwHighDateTime = (UINT)(t >> 32);
459 return FileTimeToSystemTime(&ft, lpUniversalTime);
463 /***********************************************************************
464 * GetSystemTimeAsFileTime (KERNEL32.@)
466 * Get the current time in utc format.
471 VOID WINAPI GetSystemTimeAsFileTime(
472 LPFILETIME time) /* [out] Destination for the current utc time */
475 NtQuerySystemTime( &t );
476 time->dwLowDateTime = t.u.LowPart;
477 time->dwHighDateTime = t.u.HighPart;
481 /*********************************************************************
482 * TIME_ClockTimeToFileTime (olorin@fandra.org, 20-Sep-1998)
484 * Used by GetProcessTimes to convert clock_t into FILETIME.
486 * Differences to UnixTimeToFileTime:
487 * 1) Divided by CLK_TCK
488 * 2) Time is relative. There is no 'starting date', so there is
489 * no need for offset correction, like in UnixTimeToFileTime
491 static void TIME_ClockTimeToFileTime(clock_t unix_time, LPFILETIME filetime)
493 ULONGLONG secs = RtlEnlargedUnsignedMultiply( unix_time, 10000000 );
494 secs = RtlExtendedLargeIntegerDivide( secs, CLK_TCK, NULL );
495 filetime->dwLowDateTime = (DWORD)secs;
496 filetime->dwHighDateTime = (DWORD)(secs >> 32);
499 /*********************************************************************
500 * GetProcessTimes (KERNEL32.@)
502 * Get the user and kernel execution times of a process,
503 * along with the creation and exit times if known.
510 * Would be nice to subtract the cpu time used by Wine at startup.
511 * Also, there is a need to separate times used by different applications.
514 * lpCreationTime and lpExitTime are not initialised in the Wine implementation.
516 BOOL WINAPI GetProcessTimes(
517 HANDLE hprocess, /* [in] The process to be queried (obtained from PROCESS_QUERY_INFORMATION). */
518 LPFILETIME lpCreationTime, /* [out] The creation time of the process. */
519 LPFILETIME lpExitTime, /* [out] The exit time of the process if exited. */
520 LPFILETIME lpKernelTime, /* [out] The time spent in kernal routines in 100's of nanoseconds. */
521 LPFILETIME lpUserTime) /* [out] The time spent in user routines in 100's of nanoseconds. */
526 TIME_ClockTimeToFileTime(tms.tms_utime,lpUserTime);
527 TIME_ClockTimeToFileTime(tms.tms_stime,lpKernelTime);
531 /*********************************************************************
532 * GetCalendarInfoA (KERNEL32.@)
535 int WINAPI GetCalendarInfoA(LCID lcid, CALID Calendar, CALTYPE CalType,
536 LPSTR lpCalData, int cchData, LPDWORD lpValue)
539 LPWSTR lpCalDataW = NULL;
541 FIXME("(%08lx,%08lx,%08lx,%p,%d,%p): quarter-stub\n",
542 lcid, Calendar, CalType, lpCalData, cchData, lpValue);
544 lcid = ConvertDefaultLocale(lcid);
546 if (NLS_IsUnicodeOnlyLcid(lcid))
548 SetLastError(ERROR_INVALID_PARAMETER);
553 !(lpCalDataW = HeapAlloc(GetProcessHeap(), 0, cchData*sizeof(WCHAR))))
556 ret = GetCalendarInfoW(lcid, Calendar, CalType, lpCalDataW, cchData, lpValue);
557 if(ret && lpCalDataW && lpCalData)
558 WideCharToMultiByte(CP_ACP, 0, lpCalDataW, cchData, lpCalData, cchData, NULL, NULL);
560 HeapFree(GetProcessHeap(), 0, lpCalDataW);
565 /*********************************************************************
566 * GetCalendarInfoW (KERNEL32.@)
568 * See GetCalendarInfoA.
570 int WINAPI GetCalendarInfoW(LCID Locale, CALID Calendar, CALTYPE CalType,
571 LPWSTR lpCalData, int cchData, LPDWORD lpValue)
573 FIXME("(%08lx,%08lx,%08lx,%p,%d,%p): quarter-stub\n",
574 Locale, Calendar, CalType, lpCalData, cchData, lpValue);
576 if (CalType & CAL_NOUSEROVERRIDE)
577 FIXME("flag CAL_NOUSEROVERRIDE used, not fully implemented\n");
578 if (CalType & CAL_USE_CP_ACP)
579 FIXME("flag CAL_USE_CP_ACP used, not fully implemented\n");
581 if (CalType & CAL_RETURN_NUMBER) {
582 if (lpCalData != NULL)
583 WARN("lpCalData not NULL (%p) when it should!\n", lpCalData);
585 WARN("cchData not 0 (%d) when it should!\n", cchData);
588 WARN("lpValue not NULL (%p) when it should!\n", lpValue);
591 /* FIXME: No verification is made yet wrt Locale
592 * for the CALTYPES not requiring GetLocaleInfoA */
593 switch (CalType & ~(CAL_NOUSEROVERRIDE|CAL_RETURN_NUMBER|CAL_USE_CP_ACP)) {
594 case CAL_ICALINTVALUE:
595 FIXME("Unimplemented caltype %ld\n", CalType & 0xffff);
598 FIXME("Unimplemented caltype %ld\n", CalType & 0xffff);
600 case CAL_IYEAROFFSETRANGE:
601 FIXME("Unimplemented caltype %ld\n", CalType & 0xffff);
604 FIXME("Unimplemented caltype %ld\n", CalType & 0xffff);
607 return GetLocaleInfoW(Locale, LOCALE_SSHORTDATE, lpCalData, cchData);
609 return GetLocaleInfoW(Locale, LOCALE_SLONGDATE, lpCalData, cchData);
611 return GetLocaleInfoW(Locale, LOCALE_SDAYNAME1, lpCalData, cchData);
613 return GetLocaleInfoW(Locale, LOCALE_SDAYNAME2, lpCalData, cchData);
615 return GetLocaleInfoW(Locale, LOCALE_SDAYNAME3, lpCalData, cchData);
617 return GetLocaleInfoW(Locale, LOCALE_SDAYNAME4, lpCalData, cchData);
619 return GetLocaleInfoW(Locale, LOCALE_SDAYNAME5, lpCalData, cchData);
621 return GetLocaleInfoW(Locale, LOCALE_SDAYNAME6, lpCalData, cchData);
623 return GetLocaleInfoW(Locale, LOCALE_SDAYNAME7, lpCalData, cchData);
624 case CAL_SABBREVDAYNAME1:
625 return GetLocaleInfoW(Locale, LOCALE_SABBREVDAYNAME1, lpCalData, cchData);
626 case CAL_SABBREVDAYNAME2:
627 return GetLocaleInfoW(Locale, LOCALE_SABBREVDAYNAME2, lpCalData, cchData);
628 case CAL_SABBREVDAYNAME3:
629 return GetLocaleInfoW(Locale, LOCALE_SABBREVDAYNAME3, lpCalData, cchData);
630 case CAL_SABBREVDAYNAME4:
631 return GetLocaleInfoW(Locale, LOCALE_SABBREVDAYNAME4, lpCalData, cchData);
632 case CAL_SABBREVDAYNAME5:
633 return GetLocaleInfoW(Locale, LOCALE_SABBREVDAYNAME5, lpCalData, cchData);
634 case CAL_SABBREVDAYNAME6:
635 return GetLocaleInfoW(Locale, LOCALE_SABBREVDAYNAME6, lpCalData, cchData);
636 case CAL_SABBREVDAYNAME7:
637 return GetLocaleInfoW(Locale, LOCALE_SABBREVDAYNAME7, lpCalData, cchData);
638 case CAL_SMONTHNAME1:
639 return GetLocaleInfoW(Locale, LOCALE_SMONTHNAME1, lpCalData, cchData);
640 case CAL_SMONTHNAME2:
641 return GetLocaleInfoW(Locale, LOCALE_SMONTHNAME2, lpCalData, cchData);
642 case CAL_SMONTHNAME3:
643 return GetLocaleInfoW(Locale, LOCALE_SMONTHNAME3, lpCalData, cchData);
644 case CAL_SMONTHNAME4:
645 return GetLocaleInfoW(Locale, LOCALE_SMONTHNAME4, lpCalData, cchData);
646 case CAL_SMONTHNAME5:
647 return GetLocaleInfoW(Locale, LOCALE_SMONTHNAME5, lpCalData, cchData);
648 case CAL_SMONTHNAME6:
649 return GetLocaleInfoW(Locale, LOCALE_SMONTHNAME6, lpCalData, cchData);
650 case CAL_SMONTHNAME7:
651 return GetLocaleInfoW(Locale, LOCALE_SMONTHNAME7, lpCalData, cchData);
652 case CAL_SMONTHNAME8:
653 return GetLocaleInfoW(Locale, LOCALE_SMONTHNAME8, lpCalData, cchData);
654 case CAL_SMONTHNAME9:
655 return GetLocaleInfoW(Locale, LOCALE_SMONTHNAME9, lpCalData, cchData);
656 case CAL_SMONTHNAME10:
657 return GetLocaleInfoW(Locale, LOCALE_SMONTHNAME10, lpCalData, cchData);
658 case CAL_SMONTHNAME11:
659 return GetLocaleInfoW(Locale, LOCALE_SMONTHNAME11, lpCalData, cchData);
660 case CAL_SMONTHNAME12:
661 return GetLocaleInfoW(Locale, LOCALE_SMONTHNAME12, lpCalData, cchData);
662 case CAL_SMONTHNAME13:
663 return GetLocaleInfoW(Locale, LOCALE_SMONTHNAME13, lpCalData, cchData);
664 case CAL_SABBREVMONTHNAME1:
665 return GetLocaleInfoW(Locale, LOCALE_SABBREVMONTHNAME1, lpCalData, cchData);
666 case CAL_SABBREVMONTHNAME2:
667 return GetLocaleInfoW(Locale, LOCALE_SABBREVMONTHNAME2, lpCalData, cchData);
668 case CAL_SABBREVMONTHNAME3:
669 return GetLocaleInfoW(Locale, LOCALE_SABBREVMONTHNAME3, lpCalData, cchData);
670 case CAL_SABBREVMONTHNAME4:
671 return GetLocaleInfoW(Locale, LOCALE_SABBREVMONTHNAME4, lpCalData, cchData);
672 case CAL_SABBREVMONTHNAME5:
673 return GetLocaleInfoW(Locale, LOCALE_SABBREVMONTHNAME5, lpCalData, cchData);
674 case CAL_SABBREVMONTHNAME6:
675 return GetLocaleInfoW(Locale, LOCALE_SABBREVMONTHNAME6, lpCalData, cchData);
676 case CAL_SABBREVMONTHNAME7:
677 return GetLocaleInfoW(Locale, LOCALE_SABBREVMONTHNAME7, lpCalData, cchData);
678 case CAL_SABBREVMONTHNAME8:
679 return GetLocaleInfoW(Locale, LOCALE_SABBREVMONTHNAME8, lpCalData, cchData);
680 case CAL_SABBREVMONTHNAME9:
681 return GetLocaleInfoW(Locale, LOCALE_SABBREVMONTHNAME9, lpCalData, cchData);
682 case CAL_SABBREVMONTHNAME10:
683 return GetLocaleInfoW(Locale, LOCALE_SABBREVMONTHNAME10, lpCalData, cchData);
684 case CAL_SABBREVMONTHNAME11:
685 return GetLocaleInfoW(Locale, LOCALE_SABBREVMONTHNAME11, lpCalData, cchData);
686 case CAL_SABBREVMONTHNAME12:
687 return GetLocaleInfoW(Locale, LOCALE_SABBREVMONTHNAME12, lpCalData, cchData);
688 case CAL_SABBREVMONTHNAME13:
689 return GetLocaleInfoW(Locale, LOCALE_SABBREVMONTHNAME13, lpCalData, cchData);
691 return GetLocaleInfoW(Locale, LOCALE_SYEARMONTH, lpCalData, cchData);
692 case CAL_ITWODIGITYEARMAX:
693 if (lpValue) *lpValue = CALINFO_MAX_YEAR;
695 default: MESSAGE("Unknown caltype %ld\n",CalType & 0xffff);
701 /*********************************************************************
702 * SetCalendarInfoA (KERNEL32.@)
705 int WINAPI SetCalendarInfoA(LCID Locale, CALID Calendar, CALTYPE CalType, LPCSTR lpCalData)
707 FIXME("(%08lx,%08lx,%08lx,%s): stub\n",
708 Locale, Calendar, CalType, debugstr_a(lpCalData));
712 /*********************************************************************
713 * SetCalendarInfoW (KERNEL32.@)
715 * See SetCalendarInfoA.
717 int WINAPI SetCalendarInfoW(LCID Locale, CALID Calendar, CALTYPE CalType, LPCWSTR lpCalData)
719 FIXME("(%08lx,%08lx,%08lx,%s): stub\n",
720 Locale, Calendar, CalType, debugstr_w(lpCalData));
724 /*********************************************************************
725 * LocalFileTimeToFileTime (KERNEL32.@)
727 BOOL WINAPI LocalFileTimeToFileTime( const FILETIME *localft, LPFILETIME utcft )
730 LARGE_INTEGER local, utc;
732 local.u.LowPart = localft->dwLowDateTime;
733 local.u.HighPart = localft->dwHighDateTime;
734 if (!(status = RtlLocalTimeToSystemTime( &local, &utc )))
736 utcft->dwLowDateTime = utc.u.LowPart;
737 utcft->dwHighDateTime = utc.u.HighPart;
739 else SetLastError( RtlNtStatusToDosError(status) );
744 /*********************************************************************
745 * FileTimeToLocalFileTime (KERNEL32.@)
747 BOOL WINAPI FileTimeToLocalFileTime( const FILETIME *utcft, LPFILETIME localft )
750 LARGE_INTEGER local, utc;
752 utc.u.LowPart = utcft->dwLowDateTime;
753 utc.u.HighPart = utcft->dwHighDateTime;
754 if (!(status = RtlSystemTimeToLocalTime( &utc, &local )))
756 localft->dwLowDateTime = local.u.LowPart;
757 localft->dwHighDateTime = local.u.HighPart;
759 else SetLastError( RtlNtStatusToDosError(status) );
764 /*********************************************************************
765 * FileTimeToSystemTime (KERNEL32.@)
767 BOOL WINAPI FileTimeToSystemTime( const FILETIME *ft, LPSYSTEMTIME syst )
772 t.u.LowPart = ft->dwLowDateTime;
773 t.u.HighPart = ft->dwHighDateTime;
774 RtlTimeToTimeFields(&t, &tf);
776 syst->wYear = tf.Year;
777 syst->wMonth = tf.Month;
779 syst->wHour = tf.Hour;
780 syst->wMinute = tf.Minute;
781 syst->wSecond = tf.Second;
782 syst->wMilliseconds = tf.Milliseconds;
783 syst->wDayOfWeek = tf.Weekday;
787 /*********************************************************************
788 * SystemTimeToFileTime (KERNEL32.@)
790 BOOL WINAPI SystemTimeToFileTime( const SYSTEMTIME *syst, LPFILETIME ft )
795 tf.Year = syst->wYear;
796 tf.Month = syst->wMonth;
798 tf.Hour = syst->wHour;
799 tf.Minute = syst->wMinute;
800 tf.Second = syst->wSecond;
801 tf.Milliseconds = syst->wMilliseconds;
803 RtlTimeFieldsToTime(&tf, &t);
804 ft->dwLowDateTime = t.u.LowPart;
805 ft->dwHighDateTime = t.u.HighPart;
809 /*********************************************************************
810 * CompareFileTime (KERNEL32.@)
812 * Compare two FILETIME's to each other.
816 * y [I] time to compare to x
819 * -1, 0, or 1 indicating that x is less than, equal to, or greater
820 * than y respectively.
822 INT WINAPI CompareFileTime( const FILETIME *x, const FILETIME *y )
824 if (!x || !y) return -1;
826 if (x->dwHighDateTime > y->dwHighDateTime)
828 if (x->dwHighDateTime < y->dwHighDateTime)
830 if (x->dwLowDateTime > y->dwLowDateTime)
832 if (x->dwLowDateTime < y->dwLowDateTime)
837 /*********************************************************************
838 * GetLocalTime (KERNEL32.@)
840 * Get the current local time.
845 VOID WINAPI GetLocalTime(LPSYSTEMTIME systime) /* [O] Destination for current time */
848 LARGE_INTEGER ft, ft2;
850 NtQuerySystemTime(&ft);
851 RtlSystemTimeToLocalTime(&ft, &ft2);
852 lft.dwLowDateTime = ft2.u.LowPart;
853 lft.dwHighDateTime = ft2.u.HighPart;
854 FileTimeToSystemTime(&lft, systime);
857 /*********************************************************************
858 * GetSystemTime (KERNEL32.@)
860 * Get the current system time.
865 VOID WINAPI GetSystemTime(LPSYSTEMTIME systime) /* [O] Destination for current time */
870 NtQuerySystemTime(&t);
871 ft.dwLowDateTime = t.u.LowPart;
872 ft.dwHighDateTime = t.u.HighPart;
873 FileTimeToSystemTime(&ft, systime);
876 /*********************************************************************
877 * GetDaylightFlag (KERNEL32.@)
879 * returns TRUE if daylight saving time is in operation
881 * Note: this function is called from the Win98's control applet
884 BOOL WINAPI GetDaylightFlag(void)
886 time_t t = time(NULL);
887 struct tm *ptm = localtime( &t);
888 return ptm->tm_isdst > 0;