]> git.proxmox.com Git - mirror_edk2.git/blame - EmbeddedPkg/Library/TimeBaseLib/TimeBaseLib.c
EmbeddedPkg/TimeBaseLib: Fix for minor code formatting
[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
1d757116 4* Copyright (c) 2016-2019, Linaro Limited. All rights reserved.\r
48de23e5 5* Copyright (c) 2021, Ampere Computing LLC. All rights reserved.\r
b4895995 6*\r
878b807a 7* SPDX-License-Identifier: BSD-2-Clause-Patent\r
b4895995
LL
8*\r
9**/\r
10\r
11#include <Uefi/UefiBaseType.h>\r
12#include <Uefi/UefiSpec.h>\r
13#include <Library/DebugLib.h>\r
14#include <Library/TimeBaseLib.h>\r
15\r
16/**\r
48de23e5
NP
17 Converts Epoch seconds (elapsed since 1970 JANUARY 01, 00:00:00 UTC) to EFI_TIME.\r
18\r
19 @param EpochSeconds Epoch seconds.\r
20 @param Time The time converted to UEFI format.\r
21\r
22**/\r
b4895995
LL
23VOID\r
24EFIAPI\r
25EpochToEfiTime (\r
26 IN UINTN EpochSeconds,\r
27 OUT EFI_TIME *Time\r
28 )\r
29{\r
30 UINTN a;\r
31 UINTN b;\r
32 UINTN c;\r
33 UINTN d;\r
34 UINTN g;\r
35 UINTN j;\r
36 UINTN m;\r
37 UINTN y;\r
38 UINTN da;\r
39 UINTN db;\r
40 UINTN dc;\r
41 UINTN dg;\r
42 UINTN hh;\r
43 UINTN mm;\r
44 UINTN ss;\r
45 UINTN J;\r
46\r
47 J = (EpochSeconds / 86400) + 2440588;\r
48 j = J + 32044;\r
49 g = j / 146097;\r
50 dg = j % 146097;\r
51 c = (((dg / 36524) + 1) * 3) / 4;\r
52 dc = dg - (c * 36524);\r
53 b = dc / 1461;\r
54 db = dc % 1461;\r
55 a = (((db / 365) + 1) * 3) / 4;\r
56 da = db - (a * 365);\r
57 y = (g * 400) + (c * 100) + (b * 4) + a;\r
58 m = (((da * 5) + 308) / 153) - 2;\r
59 d = da - (((m + 4) * 153) / 5) + 122;\r
60\r
1d757116 61 Time->Year = (UINT16)(y - 4800 + ((m + 2) / 12));\r
b4895995 62 Time->Month = ((m + 2) % 12) + 1;\r
1d757116 63 Time->Day = (UINT8)(d + 1);\r
b4895995
LL
64\r
65 ss = EpochSeconds % 60;\r
66 a = (EpochSeconds - ss) / 60;\r
67 mm = a % 60;\r
68 b = (a - mm) / 60;\r
69 hh = b % 24;\r
70\r
1d757116
LL
71 Time->Hour = (UINT8)hh;\r
72 Time->Minute = (UINT8)mm;\r
73 Time->Second = (UINT8)ss;\r
b4895995
LL
74 Time->Nanosecond = 0;\r
75\r
76}\r
77\r
78/**\r
48de23e5
NP
79 Calculate Epoch days.\r
80\r
81 @param Time The UEFI time to be calculated.\r
82\r
83 @return Number of days.\r
84\r
85**/\r
b4895995
LL
86UINTN\r
87EFIAPI\r
91c31ff0 88EfiGetEpochDays (\r
b4895995
LL
89 IN EFI_TIME *Time\r
90 )\r
91{\r
92 UINTN a;\r
93 UINTN y;\r
94 UINTN m;\r
95 UINTN JulianDate; // Absolute Julian Date representation of the supplied Time\r
96 UINTN EpochDays; // Number of days elapsed since EPOCH_JULIAN_DAY\r
b4895995
LL
97\r
98 a = (14 - Time->Month) / 12 ;\r
99 y = Time->Year + 4800 - a;\r
100 m = Time->Month + (12*a) - 3;\r
101\r
102 JulianDate = Time->Day + ((153*m + 2)/5) + (365*y) + (y/4) - (y/100) + (y/400) - 32045;\r
103\r
104 ASSERT (JulianDate >= EPOCH_JULIAN_DATE);\r
105 EpochDays = JulianDate - EPOCH_JULIAN_DATE;\r
106\r
91c31ff0
MA
107 return EpochDays;\r
108}\r
48de23e5 109\r
91c31ff0 110/**\r
48de23e5
NP
111 Converts EFI_TIME to Epoch seconds (elapsed since 1970 JANUARY 01, 00:00:00 UTC).\r
112\r
113 @param Time The UEFI time to be converted.\r
114\r
115 @return Number of seconds.\r
116\r
117**/\r
c06635ea 118UINTN\r
91c31ff0
MA
119EFIAPI\r
120EfiTimeToEpoch (\r
121 IN EFI_TIME *Time\r
122 )\r
123{\r
c06635ea
LE
124 UINTN EpochDays; // Number of days elapsed since EPOCH_JULIAN_DAY\r
125 UINTN EpochSeconds;\r
91c31ff0
MA
126\r
127 EpochDays = EfiGetEpochDays (Time);\r
128\r
b4895995
LL
129 EpochSeconds = (EpochDays * SEC_PER_DAY) + ((UINTN)Time->Hour * SEC_PER_HOUR) + (Time->Minute * SEC_PER_MIN) + Time->Second;\r
130\r
131 return EpochSeconds;\r
132}\r
133\r
91c31ff0 134/**\r
48de23e5
NP
135 Get the day of the week from the UEFI time.\r
136\r
137 @param Time The UEFI time to be calculated.\r
138\r
139 @return The day of the week: Sunday=0, Monday=1, ... Saturday=6\r
140\r
141**/\r
91c31ff0
MA
142UINTN\r
143EfiTimeToWday (\r
144 IN EFI_TIME *Time\r
145 )\r
146{\r
147 UINTN EpochDays; // Number of days elapsed since EPOCH_JULIAN_DAY\r
148\r
149 EpochDays = EfiGetEpochDays (Time);\r
150\r
151 // 4=1/1/1970 was a Thursday\r
152\r
153 return (EpochDays + 4) % 7;\r
154}\r
155\r
48de23e5
NP
156/**\r
157 Check if it is a leap year.\r
158\r
159 @param Time The UEFI time to be checked.\r
160\r
161 @retval TRUE It is a leap year.\r
162 @retval FALSE It is NOT a leap year.\r
163\r
164**/\r
b4895995
LL
165BOOLEAN\r
166EFIAPI\r
167IsLeapYear (\r
168 IN EFI_TIME *Time\r
169 )\r
170{\r
171 if (Time->Year % 4 == 0) {\r
172 if (Time->Year % 100 == 0) {\r
173 if (Time->Year % 400 == 0) {\r
174 return TRUE;\r
175 } else {\r
176 return FALSE;\r
177 }\r
178 } else {\r
179 return TRUE;\r
180 }\r
181 } else {\r
182 return FALSE;\r
183 }\r
184}\r
185\r
48de23e5
NP
186/**\r
187 Check if the day in the UEFI time is valid.\r
188\r
189 @param Time The UEFI time to be checked.\r
190\r
191 @retval TRUE Valid.\r
192 @retval FALSE Invalid.\r
193\r
194**/\r
b4895995
LL
195BOOLEAN\r
196EFIAPI\r
197IsDayValid (\r
198 IN EFI_TIME *Time\r
199 )\r
200{\r
201 STATIC CONST INTN DayOfMonth[12] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };\r
202\r
203 if (Time->Day < 1 ||\r
204 Time->Day > DayOfMonth[Time->Month - 1] ||\r
205 (Time->Month == 2 && (!IsLeapYear (Time) && Time->Day > 28))\r
206 ) {\r
207 return FALSE;\r
208 }\r
209\r
210 return TRUE;\r
211}\r
212\r
48de23e5
NP
213/**\r
214 Check if the UEFI time is valid.\r
215\r
216 @param Time The UEFI time to be checked.\r
217\r
218 @retval TRUE Valid.\r
219 @retval FALSE Invalid.\r
220\r
221**/\r
b4895995
LL
222BOOLEAN\r
223EFIAPI\r
ad16388d 224IsTimeValid (\r
b4895995
LL
225 IN EFI_TIME *Time\r
226 )\r
227{\r
228 // Check the input parameters are within the range specified by UEFI\r
ad16388d
NP
229 if ((Time->Year < 2000) ||\r
230 (Time->Year > 2099) ||\r
231 (Time->Month < 1 ) ||\r
232 (Time->Month > 12 ) ||\r
233 (!IsDayValid (Time) ) ||\r
234 (Time->Hour > 23 ) ||\r
235 (Time->Minute > 59 ) ||\r
236 (Time->Second > 59 ) ||\r
237 (Time->Nanosecond > 999999999) ||\r
b4895995 238 (!((Time->TimeZone == EFI_UNSPECIFIED_TIMEZONE) || ((Time->TimeZone >= -1440) && (Time->TimeZone <= 1440)))) ||\r
ad16388d 239 (Time->Daylight & (~(EFI_TIME_ADJUST_DAYLIGHT | EFI_TIME_IN_DAYLIGHT)))) {\r
b4895995
LL
240 return FALSE;\r
241 }\r
242\r
243 return TRUE;\r
244}\r