Fix some .rbuild file problems
[reactos.git] / reactos / lib / rtl / time.c
index 0716a60..1207e92 100644 (file)
@@ -1,19 +1,14 @@
-/* $Id$
- *
- * COPYRIGHT:       See COPYING in the top level directory
- * PROJECT:         ReactOS kernel
- * FILE:            lib/rtl/time.c
- * PURPOSE:         Conversion between Time and TimeFields
- * PROGRAMMER:      Rex Jolliff (rex@lvcablemodem.com)
- * UPDATE HISTORY:
- *                  Created 22/05/98
- *   08/03/98  RJJ  Implemented these functions
+/*
+ * COPYRIGHT:         See COPYING in the top level directory
+ * PROJECT:           ReactOS system libraries
+ * FILE:              lib/rtl/time.c
+ * PURPOSE:           Conversion between Time and TimeFields
+ * PROGRAMMER:        Rex Jolliff (rex@lvcablemodem.com)
  */
 
 /* INCLUDES *****************************************************************/
 
-#include <ddk/ntddk.h>
-#include <ntdll/rtl.h>
+#include <rtl.h>
 
 #define NDEBUG
 #include <debug.h>
@@ -48,9 +43,7 @@ static const int YearLengths[2] =
    };
 static const int MonthLengths[2][MONSPERYEAR] =
    {
-      {
-         31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
-      },
+      { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
       { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
    };
 
@@ -69,14 +62,113 @@ static __inline void NormalizeTimeFields(CSHORT *FieldToNormalize,
 
 /* FUNCTIONS *****************************************************************/
 
+/*
+ * @implemented
+ */
+BOOLEAN NTAPI
+RtlCutoverTimeToSystemTime(IN PTIME_FIELDS CutoverTimeFields,
+                           OUT PLARGE_INTEGER SystemTime,
+                           IN PLARGE_INTEGER CurrentTime,
+                           IN BOOLEAN ThisYearsCutoverOnly)
+{
+  TIME_FIELDS AdjustedTimeFields;
+  TIME_FIELDS CurrentTimeFields;
+  TIME_FIELDS CutoverSystemTimeFields;
+  LARGE_INTEGER CutoverSystemTime;
+  CSHORT MonthLength;
+  CSHORT Days;
+  BOOLEAN NextYearsCutover = FALSE;
+
+  /* Check fixed cutover time */
+  if (CutoverTimeFields->Year != 0)
+  {
+    if (!RtlTimeFieldsToTime(CutoverTimeFields, SystemTime))
+      return FALSE;
+
+    if (SystemTime->QuadPart < CurrentTime->QuadPart)
+      return FALSE;
+
+    return TRUE;
+  }
+
+  /*
+   * Compute recurring cutover time
+   */
+
+  /* Day must be between 1(first) and 5(last) */
+  if (CutoverTimeFields->Day == 0 || CutoverTimeFields->Day > 5)
+    return FALSE;
+
+  RtlTimeToTimeFields(CurrentTime, &CurrentTimeFields);
+
+  while (TRUE)
+  {
+    /* Compute the cutover time of the first day of the current month */
+    AdjustedTimeFields.Year = CurrentTimeFields.Year;
+    if (NextYearsCutover == TRUE)
+      AdjustedTimeFields.Year++;
+
+    AdjustedTimeFields.Month = CutoverTimeFields->Month;
+    AdjustedTimeFields.Day = 1;
+    AdjustedTimeFields.Hour = CutoverTimeFields->Hour;
+    AdjustedTimeFields.Minute = CutoverTimeFields->Minute;
+    AdjustedTimeFields.Second = CutoverTimeFields->Second;
+    AdjustedTimeFields.Milliseconds = CutoverTimeFields->Milliseconds;
+
+    if (!RtlTimeFieldsToTime(&AdjustedTimeFields, &CutoverSystemTime))
+      return FALSE;
+
+    RtlTimeToTimeFields(&CutoverSystemTime, &CutoverSystemTimeFields);
+
+    /* Adjust day to first matching weekday */
+    if (CutoverSystemTimeFields.Weekday != CutoverTimeFields->Weekday)
+    {
+      if (CutoverSystemTimeFields.Weekday < CutoverTimeFields->Weekday)
+        Days = CutoverTimeFields->Weekday - CutoverSystemTimeFields.Weekday;
+      else
+        Days = DAYSPERWEEK - (CutoverSystemTimeFields.Weekday - CutoverTimeFields->Weekday);
+
+      AdjustedTimeFields.Day += Days;
+    }
+
+    /* Adjust the number of weeks */
+    if (CutoverTimeFields->Day > 1)
+    {
+      Days = DAYSPERWEEK * (CutoverTimeFields->Day - 1);
+      MonthLength = MonthLengths[IsLeapYear(AdjustedTimeFields.Year)][AdjustedTimeFields.Month - 1];
+      if ((AdjustedTimeFields.Day + Days) > MonthLength)
+        Days -= DAYSPERWEEK;
+
+      AdjustedTimeFields.Day += Days;
+    }
+
+    if (!RtlTimeFieldsToTime(&AdjustedTimeFields, &CutoverSystemTime))
+      return FALSE;
+
+    if (ThisYearsCutoverOnly == TRUE ||
+        NextYearsCutover == TRUE ||
+        CutoverSystemTime.QuadPart >= CurrentTime->QuadPart)
+    {
+      break;
+    }
+
+    NextYearsCutover = TRUE;
+  }
+
+  SystemTime->QuadPart = CutoverSystemTime.QuadPart;
+
+  return TRUE;
+}
+
+
 /*
  * @implemented
  */
 BOOLEAN
-STDCALL
+NTAPI
 RtlTimeFieldsToTime(
-   PTIME_FIELDS TimeFields,
-   PLARGE_INTEGER Time)
+   IN PTIME_FIELDS TimeFields,
+   OUT PLARGE_INTEGER Time)
 {
    int CurYear;
    int CurMonth;
@@ -144,7 +236,7 @@ RtlTimeFieldsToTime(
  * @implemented
  */
 VOID
-STDCALL
+NTAPI
 RtlTimeToElapsedTimeFields(IN PLARGE_INTEGER Time,
                            OUT PTIME_FIELDS TimeFields)
 {
@@ -179,13 +271,13 @@ RtlTimeToElapsedTimeFields(IN PLARGE_INTEGER Time,
 
 
 /*
- * @unimplemented
+ * @implemented
  */
 VOID
-STDCALL
+NTAPI
 RtlTimeToTimeFields(
-   PLARGE_INTEGER Time,
-   PTIME_FIELDS TimeFields)
+   IN PLARGE_INTEGER Time,
+   OUT PTIME_FIELDS TimeFields)
 {
    const int *Months;
    int SecondsInDay, CurYear;
@@ -230,7 +322,6 @@ RtlTimeToTimeFields(
    Days += CurYear - CurYear / 4 + CurYear / 100 - CurYear / 400;
    CurYear++;
    Days -= EPOCHYEAR - 1 - (EPOCHYEAR -1) / 4 + (EPOCHYEAR -1) / 100 - (EPOCHYEAR - 1) / 400;
-   /* FIXME: handle calendar modifications */
    while (1)
    {
       LeapYear = IsLeapYear(CurYear);
@@ -257,10 +348,10 @@ RtlTimeToTimeFields(
  * @implemented
  */
 BOOLEAN
-STDCALL
+NTAPI
 RtlTimeToSecondsSince1970(
-   PLARGE_INTEGER Time,
-   PULONG SecondsSince1970)
+   IN PLARGE_INTEGER Time,
+   OUT PULONG SecondsSince1970)
 {
    LARGE_INTEGER IntTime;
 
@@ -280,10 +371,10 @@ RtlTimeToSecondsSince1970(
  * @implemented
  */
 BOOLEAN
-STDCALL
+NTAPI
 RtlTimeToSecondsSince1980(
-   PLARGE_INTEGER Time,
-   PULONG SecondsSince1980)
+   IN PLARGE_INTEGER Time,
+   OUT PULONG SecondsSince1980)
 {
    LARGE_INTEGER IntTime;
 
@@ -303,24 +394,24 @@ RtlTimeToSecondsSince1980(
  * @implemented
  */
 NTSTATUS
-STDCALL
-RtlLocalTimeToSystemTime(PLARGE_INTEGER LocalTime,
-                         PLARGE_INTEGER SystemTime)
+NTAPI
+RtlLocalTimeToSystemTime(IN PLARGE_INTEGER LocalTime,
+                         OUT PLARGE_INTEGER SystemTime)
 {
    SYSTEM_TIMEOFDAY_INFORMATION TimeInformation;
    NTSTATUS Status;
 
-   Status = NtQuerySystemInformation(SystemTimeOfDayInformation,
+   Status = ZwQuerySystemInformation(SystemTimeOfDayInformation,
                                      &TimeInformation,
                                      sizeof(SYSTEM_TIMEOFDAY_INFORMATION),
                                      NULL);
    if (!NT_SUCCESS(Status))
-      return(Status);
+      return Status;
 
    SystemTime->QuadPart = LocalTime->QuadPart +
                           TimeInformation.TimeZoneBias.QuadPart;
 
-   return(STATUS_SUCCESS);
+   return STATUS_SUCCESS;
 }
 
 
@@ -328,48 +419,46 @@ RtlLocalTimeToSystemTime(PLARGE_INTEGER LocalTime,
  * @implemented
  */
 NTSTATUS
-STDCALL
-RtlSystemTimeToLocalTime(PLARGE_INTEGER SystemTime,
-                         PLARGE_INTEGER LocalTime)
+NTAPI
+RtlSystemTimeToLocalTime(IN PLARGE_INTEGER SystemTime,
+                         OUT PLARGE_INTEGER LocalTime)
 {
    SYSTEM_TIMEOFDAY_INFORMATION TimeInformation;
    NTSTATUS Status;
 
-   Status = NtQuerySystemInformation(SystemTimeOfDayInformation,
+   Status = ZwQuerySystemInformation(SystemTimeOfDayInformation,
                                      &TimeInformation,
                                      sizeof(SYSTEM_TIMEOFDAY_INFORMATION),
                                      NULL);
    if (!NT_SUCCESS(Status))
-      return(Status);
+      return Status;
 
    LocalTime->QuadPart = SystemTime->QuadPart -
                          TimeInformation.TimeZoneBias.QuadPart;
 
-   return(STATUS_SUCCESS);
+   return STATUS_SUCCESS;
 }
 
 
 /*
  * @implemented
  */
-VOID
-STDCALL
+VOID NTAPI
 RtlSecondsSince1970ToTime(
-   ULONG SecondsSince1970,
-   PLARGE_INTEGER Time)
+   IN ULONG SecondsSince1970,
+   OUT PLARGE_INTEGER Time)
 {
-   Time->QuadPart = ((LONGLONG)SecondsSince1970 * TICKSPERSEC) + TICKSTO1970;
+  Time->QuadPart = ((LONGLONG)SecondsSince1970 * TICKSPERSEC) + TICKSTO1970;
 }
 
 
 /*
  * @implemented
  */
-VOID
-STDCALL
+VOID NTAPI
 RtlSecondsSince1980ToTime(
-   ULONG SecondsSince1980,
-   PLARGE_INTEGER Time)
+   IN ULONG SecondsSince1980,
+   OUT PLARGE_INTEGER Time)
 {
    Time->QuadPart = ((LONGLONG)SecondsSince1980 * TICKSPERSEC) + TICKSTO1980;
 }