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