copied from ntoskrnl/rtl/time.c
authorjean <jean@svn.reactos.org>
Tue, 16 Feb 1999 12:37:48 +0000 (12:37 +0000)
committerjean <jean@svn.reactos.org>
Tue, 16 Feb 1999 12:37:48 +0000 (12:37 +0000)
svn path=/trunk/; revision=240

reactos/lib/ntdll/rtl/time.c [new file with mode: 0644]

diff --git a/reactos/lib/ntdll/rtl/time.c b/reactos/lib/ntdll/rtl/time.c
new file mode 100644 (file)
index 0000000..be78a12
--- /dev/null
@@ -0,0 +1,204 @@
+/*
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS kernel
+ * FILE:            kernel/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
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+
+#include <internal/debug.h>
+
+#define TICKSPERSEC        10000000
+#define TICKSPERMSEC       10000
+#define SECSPERDAY         86400
+#define SECSPERHOUR        3600
+#define SECSPERMIN         60
+#define MINSPERHOUR        60
+#define HOURSPERDAY        24
+#define EPOCHWEEKDAY       0
+#define DAYSPERWEEK        7
+#define EPOCHYEAR          1601
+#define DAYSPERNORMALYEAR  365
+#define DAYSPERLEAPYEAR    366
+#define MONSPERYEAR        12
+
+static const int YearLengths[2] = {DAYSPERNORMALYEAR, DAYSPERLEAPYEAR};
+static const int MonthLengths[2][MONSPERYEAR] =
+{
+       { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
+       { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
+};
+
+static __inline int IsLeapYear(int Year)
+{
+  return Year % 4 == 0 && (Year % 100 != 0 || Year % 400 == 0) ? 1 : 0;
+}
+
+static __inline void NormalizeTimeFields(CSHORT *FieldToNormalize,
+                                         CSHORT *CarryField,
+                                         int Modulus)
+{
+  *FieldToNormalize = (CSHORT) (*FieldToNormalize - Modulus);
+  *CarryField = (CSHORT) (*CarryField + 1);
+}
+
+/* FUNCTIONS *****************************************************************/
+
+VOID RtlTimeToTimeFields(PLARGE_INTEGER liTime,
+                        PTIME_FIELDS TimeFields)
+{
+
+#if 1
+
+  const int *Months;
+  int LeapSecondCorrections, SecondsInDay, CurYear;
+  int LeapYear, CurMonth, GMTOffset;
+  long int Days;
+  long long int Time = *(long long int *)liTime;
+
+    /* Extract millisecond from time and convert time into seconds */
+  TimeFields->Milliseconds = (CSHORT) ((Time % TICKSPERSEC) / TICKSPERMSEC);
+  Time = Time / TICKSPERSEC;
+
+    /* FIXME: Compute the number of leap second corrections here */
+  LeapSecondCorrections = 0;
+
+    /* FIXME: get the GMT offset here */
+  GMTOffset = 0;
+
+    /* Split the time into days and seconds within the day */
+  Days = Time / SECSPERDAY;
+  SecondsInDay = Time % SECSPERDAY;
+
+    /* Adjust the values for GMT and leap seconds */
+  SecondsInDay += (GMTOffset - LeapSecondCorrections);
+  while (SecondsInDay < 0) 
+    {
+      SecondsInDay += SECSPERDAY;
+      Days--;
+    }
+  while (SecondsInDay >= SECSPERDAY) 
+    {
+      SecondsInDay -= SECSPERDAY;
+      Days++;
+    }
+
+    /* compute time of day */
+  TimeFields->Hour = (CSHORT) (SecondsInDay / SECSPERHOUR);
+  SecondsInDay = SecondsInDay % SECSPERHOUR;
+  TimeFields->Minute = (CSHORT) (SecondsInDay / SECSPERMIN);
+  TimeFields->Second = (CSHORT) (SecondsInDay % SECSPERMIN);
+
+    /* FIXME: handle the possibility that we are on a leap second (i.e. Second = 60) */
+
+    /* compute day of week */
+  TimeFields->Weekday = (CSHORT) ((EPOCHWEEKDAY + Days) % DAYSPERWEEK);
+
+    /* compute year */
+  CurYear = EPOCHYEAR;
+    /* FIXME: handle calendar modifications */
+  while (1)
+    {
+      LeapYear = IsLeapYear(CurYear);
+      if (Days < (long) YearLengths[LeapYear])
+        {
+          break;
+        }
+      CurYear++;
+      Days = Days - (long) YearLengths[LeapYear];
+    }
+  TimeFields->Year = (CSHORT) CurYear;
+
+    /* Compute month of year */
+  Months = MonthLengths[LeapYear];
+  for (CurMonth = 0; Days >= (long) Months[CurMonth]; CurMonth++)
+    Days = Days - (long) Months[CurMonth];
+  TimeFields->Month = (CSHORT) (CurMonth + 1);
+  TimeFields->Day = (CSHORT) (Days + 1);
+
+#else
+
+   UNIMPLEMENTED;
+
+#endif
+
+}
+
+BOOLEAN RtlTimeFieldsToTime(PTIME_FIELDS tfTimeFields,
+                           PLARGE_INTEGER Time)
+{
+
+#if 1
+
+  int CurYear, CurMonth;
+  long long int rcTime;
+  TIME_FIELDS TimeFields = *tfTimeFields;
+
+  rcTime = 0;
+  
+    /* FIXME: normalize the TIME_FIELDS structure here */
+  while (TimeFields.Second >= SECSPERMIN)
+    {
+      NormalizeTimeFields(&TimeFields.Second, 
+                          &TimeFields.Minute, 
+                          SECSPERMIN);
+    }
+  while (TimeFields.Minute >= MINSPERHOUR)
+    {
+      NormalizeTimeFields(&TimeFields.Minute, 
+                          &TimeFields.Hour, 
+                          MINSPERHOUR);
+    }
+  while (TimeFields.Hour >= HOURSPERDAY)
+    {
+      NormalizeTimeFields(&TimeFields.Hour, 
+                          &TimeFields.Day, 
+                          HOURSPERDAY);
+    }
+  while (TimeFields.Day >
+         MonthLengths[IsLeapYear(TimeFields.Year)][TimeFields.Month - 1])
+    {
+      NormalizeTimeFields(&TimeFields.Day, 
+                          &TimeFields.Month, 
+                          SECSPERMIN);
+    }
+  while (TimeFields.Month > MONSPERYEAR)
+    {
+      NormalizeTimeFields(&TimeFields.Month, 
+                          &TimeFields.Year, 
+                          MONSPERYEAR);
+    }
+
+    /* FIXME: handle calendar corrections here */
+  for (CurYear = EPOCHYEAR; CurYear < TimeFields.Year; CurYear++)
+    {
+      rcTime += YearLengths[IsLeapYear(CurYear)];
+    }
+  for (CurMonth = 1; CurMonth < TimeFields.Month; CurMonth++)
+    {
+      rcTime += MonthLengths[IsLeapYear(CurYear)][CurMonth - 1];
+    }
+  rcTime += TimeFields.Day - 1;
+  rcTime *= SECSPERDAY;
+  rcTime += TimeFields.Hour * SECSPERHOUR + TimeFields.Minute * SECSPERMIN +
+            TimeFields.Second;
+  rcTime *= TICKSPERSEC;
+  rcTime += TimeFields.Milliseconds * TICKSPERMSEC;
+  *Time = *(LARGE_INTEGER *)&rcTime;
+
+  return TRUE;
+
+#else
+
+   UNIMPLEMENTED;
+
+#endif
+
+}