]> git.proxmox.com Git - mirror_edk2.git/blame - EmbeddedPkg/Library/TimeBaseLib/TimeBaseLib.c
EmbeddedPkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / EmbeddedPkg / Library / TimeBaseLib / TimeBaseLib.c
CommitLineData
b4895995
LL
1/** @file\r
2*\r
3* Copyright (c) 2016, Hisilicon Limited. All rights reserved.\r
4* Copyright (c) 2016, Linaro Limited. All rights reserved.\r
5*\r
878b807a 6* SPDX-License-Identifier: BSD-2-Clause-Patent\r
b4895995
LL
7*\r
8**/\r
9\r
10#include <Uefi/UefiBaseType.h>\r
11#include <Uefi/UefiSpec.h>\r
12#include <Library/DebugLib.h>\r
13#include <Library/TimeBaseLib.h>\r
14\r
15/**\r
16 Converts Epoch seconds (elapsed since 1970 JANUARY 01, 00:00:00 UTC) to EFI_TIME\r
17 **/\r
18VOID\r
19EFIAPI\r
20EpochToEfiTime (\r
21 IN UINTN EpochSeconds,\r
22 OUT EFI_TIME *Time\r
23 )\r
24{\r
25 UINTN a;\r
26 UINTN b;\r
27 UINTN c;\r
28 UINTN d;\r
29 UINTN g;\r
30 UINTN j;\r
31 UINTN m;\r
32 UINTN y;\r
33 UINTN da;\r
34 UINTN db;\r
35 UINTN dc;\r
36 UINTN dg;\r
37 UINTN hh;\r
38 UINTN mm;\r
39 UINTN ss;\r
40 UINTN J;\r
41\r
42 J = (EpochSeconds / 86400) + 2440588;\r
43 j = J + 32044;\r
44 g = j / 146097;\r
45 dg = j % 146097;\r
46 c = (((dg / 36524) + 1) * 3) / 4;\r
47 dc = dg - (c * 36524);\r
48 b = dc / 1461;\r
49 db = dc % 1461;\r
50 a = (((db / 365) + 1) * 3) / 4;\r
51 da = db - (a * 365);\r
52 y = (g * 400) + (c * 100) + (b * 4) + a;\r
53 m = (((da * 5) + 308) / 153) - 2;\r
54 d = da - (((m + 4) * 153) / 5) + 122;\r
55\r
56 Time->Year = y - 4800 + ((m + 2) / 12);\r
57 Time->Month = ((m + 2) % 12) + 1;\r
58 Time->Day = d + 1;\r
59\r
60 ss = EpochSeconds % 60;\r
61 a = (EpochSeconds - ss) / 60;\r
62 mm = a % 60;\r
63 b = (a - mm) / 60;\r
64 hh = b % 24;\r
65\r
66 Time->Hour = hh;\r
67 Time->Minute = mm;\r
68 Time->Second = ss;\r
69 Time->Nanosecond = 0;\r
70\r
71}\r
72\r
73/**\r
91c31ff0 74 Calculate Epoch days\r
b4895995
LL
75 **/\r
76UINTN\r
77EFIAPI\r
91c31ff0 78EfiGetEpochDays (\r
b4895995
LL
79 IN EFI_TIME *Time\r
80 )\r
81{\r
82 UINTN a;\r
83 UINTN y;\r
84 UINTN m;\r
85 UINTN JulianDate; // Absolute Julian Date representation of the supplied Time\r
86 UINTN EpochDays; // Number of days elapsed since EPOCH_JULIAN_DAY\r
b4895995
LL
87\r
88 a = (14 - Time->Month) / 12 ;\r
89 y = Time->Year + 4800 - a;\r
90 m = Time->Month + (12*a) - 3;\r
91\r
92 JulianDate = Time->Day + ((153*m + 2)/5) + (365*y) + (y/4) - (y/100) + (y/400) - 32045;\r
93\r
94 ASSERT (JulianDate >= EPOCH_JULIAN_DATE);\r
95 EpochDays = JulianDate - EPOCH_JULIAN_DATE;\r
96\r
91c31ff0
MA
97 return EpochDays;\r
98}\r
99/**\r
100 Converts EFI_TIME to Epoch seconds (elapsed since 1970 JANUARY 01, 00:00:00 UTC)\r
101 **/\r
102UINTN\r
103EFIAPI\r
104EfiTimeToEpoch (\r
105 IN EFI_TIME *Time\r
106 )\r
107{\r
108 UINTN EpochDays; // Number of days elapsed since EPOCH_JULIAN_DAY\r
109 UINTN EpochSeconds;\r
110\r
111 EpochDays = EfiGetEpochDays (Time);\r
112\r
b4895995
LL
113 EpochSeconds = (EpochDays * SEC_PER_DAY) + ((UINTN)Time->Hour * SEC_PER_HOUR) + (Time->Minute * SEC_PER_MIN) + Time->Second;\r
114\r
115 return EpochSeconds;\r
116}\r
117\r
91c31ff0
MA
118/**\r
119 returns Day of the week [0-6] 0=Sunday\r
120 **/\r
121UINTN\r
122EfiTimeToWday (\r
123 IN EFI_TIME *Time\r
124 )\r
125{\r
126 UINTN EpochDays; // Number of days elapsed since EPOCH_JULIAN_DAY\r
127\r
128 EpochDays = EfiGetEpochDays (Time);\r
129\r
130 // 4=1/1/1970 was a Thursday\r
131\r
132 return (EpochDays + 4) % 7;\r
133}\r
134\r
b4895995
LL
135BOOLEAN\r
136EFIAPI\r
137IsLeapYear (\r
138 IN EFI_TIME *Time\r
139 )\r
140{\r
141 if (Time->Year % 4 == 0) {\r
142 if (Time->Year % 100 == 0) {\r
143 if (Time->Year % 400 == 0) {\r
144 return TRUE;\r
145 } else {\r
146 return FALSE;\r
147 }\r
148 } else {\r
149 return TRUE;\r
150 }\r
151 } else {\r
152 return FALSE;\r
153 }\r
154}\r
155\r
156BOOLEAN\r
157EFIAPI\r
158IsDayValid (\r
159 IN EFI_TIME *Time\r
160 )\r
161{\r
162 STATIC CONST INTN DayOfMonth[12] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };\r
163\r
164 if (Time->Day < 1 ||\r
165 Time->Day > DayOfMonth[Time->Month - 1] ||\r
166 (Time->Month == 2 && (!IsLeapYear (Time) && Time->Day > 28))\r
167 ) {\r
168 return FALSE;\r
169 }\r
170\r
171 return TRUE;\r
172}\r
173\r
174BOOLEAN\r
175EFIAPI\r
176IsTimeValid(\r
177 IN EFI_TIME *Time\r
178 )\r
179{\r
180 // Check the input parameters are within the range specified by UEFI\r
181 if ((Time->Year < 2000) ||\r
182 (Time->Year > 2099) ||\r
183 (Time->Month < 1 ) ||\r
184 (Time->Month > 12 ) ||\r
185 (!IsDayValid (Time) ) ||\r
186 (Time->Hour > 23 ) ||\r
187 (Time->Minute > 59 ) ||\r
188 (Time->Second > 59 ) ||\r
189 (Time->Nanosecond > 999999999) ||\r
190 (!((Time->TimeZone == EFI_UNSPECIFIED_TIMEZONE) || ((Time->TimeZone >= -1440) && (Time->TimeZone <= 1440)))) ||\r
191 (Time->Daylight & (~(EFI_TIME_ADJUST_DAYLIGHT | EFI_TIME_IN_DAYLIGHT)))\r
192 ) {\r
193 return FALSE;\r
194 }\r
195\r
196 return TRUE;\r
197}\r