]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - EmbeddedPkg/Library/TimeBaseLib/TimeBaseLib.c
EmbeddedPkg/TimeBaseLib: Update comment blocks for API functions
[mirror_edk2.git] / EmbeddedPkg / Library / TimeBaseLib / TimeBaseLib.c
... / ...
CommitLineData
1/** @file\r
2*\r
3* Copyright (c) 2016, Hisilicon Limited. All rights reserved.\r
4* Copyright (c) 2016-2019, Linaro Limited. All rights reserved.\r
5* Copyright (c) 2021, Ampere Computing LLC. All rights reserved.\r
6*\r
7* SPDX-License-Identifier: BSD-2-Clause-Patent\r
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
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
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
61 Time->Year = (UINT16)(y - 4800 + ((m + 2) / 12));\r
62 Time->Month = ((m + 2) % 12) + 1;\r
63 Time->Day = (UINT8)(d + 1);\r
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
71 Time->Hour = (UINT8)hh;\r
72 Time->Minute = (UINT8)mm;\r
73 Time->Second = (UINT8)ss;\r
74 Time->Nanosecond = 0;\r
75\r
76}\r
77\r
78/**\r
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
86UINTN\r
87EFIAPI\r
88EfiGetEpochDays (\r
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
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
107 return EpochDays;\r
108}\r
109\r
110/**\r
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
118UINTN\r
119EFIAPI\r
120EfiTimeToEpoch (\r
121 IN EFI_TIME *Time\r
122 )\r
123{\r
124 UINTN EpochDays; // Number of days elapsed since EPOCH_JULIAN_DAY\r
125 UINTN EpochSeconds;\r
126\r
127 EpochDays = EfiGetEpochDays (Time);\r
128\r
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
134/**\r
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
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
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
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
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
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
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
222BOOLEAN\r
223EFIAPI\r
224IsTimeValid(\r
225 IN EFI_TIME *Time\r
226 )\r
227{\r
228 // Check the input parameters are within the range specified by UEFI\r
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
238 (!((Time->TimeZone == EFI_UNSPECIFIED_TIMEZONE) || ((Time->TimeZone >= -1440) && (Time->TimeZone <= 1440)))) ||\r
239 (Time->Daylight & (~(EFI_TIME_ADJUST_DAYLIGHT | EFI_TIME_IN_DAYLIGHT)))\r
240 ) {\r
241 return FALSE;\r
242 }\r
243\r
244 return TRUE;\r
245}\r