]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EmbeddedPkg/Library/TimeBaseLib/TimeBaseLib.c
EmbeddedPkg: import EfiTimeBaseLib (as TimeBaseLib)
[mirror_edk2.git] / EmbeddedPkg / Library / TimeBaseLib / TimeBaseLib.c
diff --git a/EmbeddedPkg/Library/TimeBaseLib/TimeBaseLib.c b/EmbeddedPkg/Library/TimeBaseLib/TimeBaseLib.c
new file mode 100644 (file)
index 0000000..0c0d940
--- /dev/null
@@ -0,0 +1,171 @@
+/** @file\r
+*\r
+*  Copyright (c) 2016, Hisilicon Limited. All rights reserved.\r
+*  Copyright (c) 2016, Linaro Limited. All rights reserved.\r
+*\r
+*  This program and the accompanying materials\r
+*  are licensed and made available under the terms and conditions of the BSD License\r
+*  which accompanies this distribution.  The full text of the license may be found at\r
+*  http://opensource.org/licenses/bsd-license.php\r
+*\r
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+*\r
+**/\r
+\r
+#include <Uefi/UefiBaseType.h>\r
+#include <Uefi/UefiSpec.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/TimeBaseLib.h>\r
+\r
+/**\r
+  Converts Epoch seconds (elapsed since 1970 JANUARY 01, 00:00:00 UTC) to EFI_TIME\r
+ **/\r
+VOID\r
+EFIAPI\r
+EpochToEfiTime (\r
+  IN  UINTN     EpochSeconds,\r
+  OUT EFI_TIME  *Time\r
+  )\r
+{\r
+  UINTN         a;\r
+  UINTN         b;\r
+  UINTN         c;\r
+  UINTN         d;\r
+  UINTN         g;\r
+  UINTN         j;\r
+  UINTN         m;\r
+  UINTN         y;\r
+  UINTN         da;\r
+  UINTN         db;\r
+  UINTN         dc;\r
+  UINTN         dg;\r
+  UINTN         hh;\r
+  UINTN         mm;\r
+  UINTN         ss;\r
+  UINTN         J;\r
+\r
+  J  = (EpochSeconds / 86400) + 2440588;\r
+  j  = J + 32044;\r
+  g  = j / 146097;\r
+  dg = j % 146097;\r
+  c  = (((dg / 36524) + 1) * 3) / 4;\r
+  dc = dg - (c * 36524);\r
+  b  = dc / 1461;\r
+  db = dc % 1461;\r
+  a  = (((db / 365) + 1) * 3) / 4;\r
+  da = db - (a * 365);\r
+  y  = (g * 400) + (c * 100) + (b * 4) + a;\r
+  m  = (((da * 5) + 308) / 153) - 2;\r
+  d  = da - (((m + 4) * 153) / 5) + 122;\r
+\r
+  Time->Year  = y - 4800 + ((m + 2) / 12);\r
+  Time->Month = ((m + 2) % 12) + 1;\r
+  Time->Day   = d + 1;\r
+\r
+  ss = EpochSeconds % 60;\r
+  a  = (EpochSeconds - ss) / 60;\r
+  mm = a % 60;\r
+  b = (a - mm) / 60;\r
+  hh = b % 24;\r
+\r
+  Time->Hour        = hh;\r
+  Time->Minute      = mm;\r
+  Time->Second      = ss;\r
+  Time->Nanosecond  = 0;\r
+\r
+}\r
+\r
+/**\r
+  Converts EFI_TIME to Epoch seconds (elapsed since 1970 JANUARY 01, 00:00:00 UTC)\r
+ **/\r
+UINTN\r
+EFIAPI\r
+EfiTimeToEpoch (\r
+  IN  EFI_TIME  *Time\r
+  )\r
+{\r
+  UINTN a;\r
+  UINTN y;\r
+  UINTN m;\r
+  UINTN JulianDate;  // Absolute Julian Date representation of the supplied Time\r
+  UINTN EpochDays;   // Number of days elapsed since EPOCH_JULIAN_DAY\r
+  UINTN EpochSeconds;\r
+\r
+  a = (14 - Time->Month) / 12 ;\r
+  y = Time->Year + 4800 - a;\r
+  m = Time->Month + (12*a) - 3;\r
+\r
+  JulianDate = Time->Day + ((153*m + 2)/5) + (365*y) + (y/4) - (y/100) + (y/400) - 32045;\r
+\r
+  ASSERT (JulianDate >= EPOCH_JULIAN_DATE);\r
+  EpochDays = JulianDate - EPOCH_JULIAN_DATE;\r
+\r
+  EpochSeconds = (EpochDays * SEC_PER_DAY) + ((UINTN)Time->Hour * SEC_PER_HOUR) + (Time->Minute * SEC_PER_MIN) + Time->Second;\r
+\r
+  return EpochSeconds;\r
+}\r
+\r
+BOOLEAN\r
+EFIAPI\r
+IsLeapYear (\r
+  IN EFI_TIME   *Time\r
+  )\r
+{\r
+  if (Time->Year % 4 == 0) {\r
+    if (Time->Year % 100 == 0) {\r
+      if (Time->Year % 400 == 0) {\r
+        return TRUE;\r
+      } else {\r
+        return FALSE;\r
+      }\r
+    } else {\r
+      return TRUE;\r
+    }\r
+  } else {\r
+    return FALSE;\r
+  }\r
+}\r
+\r
+BOOLEAN\r
+EFIAPI\r
+IsDayValid (\r
+  IN  EFI_TIME  *Time\r
+  )\r
+{\r
+  STATIC CONST INTN DayOfMonth[12] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };\r
+\r
+  if (Time->Day < 1 ||\r
+      Time->Day > DayOfMonth[Time->Month - 1] ||\r
+      (Time->Month == 2 && (!IsLeapYear (Time) && Time->Day > 28))\r
+     ) {\r
+    return FALSE;\r
+  }\r
+\r
+  return TRUE;\r
+}\r
+\r
+BOOLEAN\r
+EFIAPI\r
+IsTimeValid(\r
+  IN EFI_TIME *Time\r
+  )\r
+{\r
+  // Check the input parameters are within the range specified by UEFI\r
+  if ((Time->Year   < 2000) ||\r
+     (Time->Year   > 2099) ||\r
+     (Time->Month  < 1   ) ||\r
+     (Time->Month  > 12  ) ||\r
+     (!IsDayValid (Time)    ) ||\r
+     (Time->Hour   > 23  ) ||\r
+     (Time->Minute > 59  ) ||\r
+     (Time->Second > 59  ) ||\r
+     (Time->Nanosecond > 999999999) ||\r
+     (!((Time->TimeZone == EFI_UNSPECIFIED_TIMEZONE) || ((Time->TimeZone >= -1440) && (Time->TimeZone <= 1440)))) ||\r
+     (Time->Daylight & (~(EFI_TIME_ADJUST_DAYLIGHT | EFI_TIME_IN_DAYLIGHT)))\r
+  ) {\r
+    return FALSE;\r
+  }\r
+\r
+  return TRUE;\r
+}\r