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.
7 * SPDX-License-Identifier: BSD-2-Clause-Patent
11 #include <Uefi/UefiBaseType.h>
12 #include <Uefi/UefiSpec.h>
13 #include <Library/DebugLib.h>
14 #include <Library/TimeBaseLib.h>
17 Converts Epoch seconds (elapsed since 1970 JANUARY 01, 00:00:00 UTC) to EFI_TIME.
19 @param EpochSeconds Epoch seconds.
20 @param Time The time converted to UEFI format.
26 IN UINTN EpochSeconds
,
47 J
= (EpochSeconds
/ 86400) + 2440588;
51 c
= (((dg
/ 36524) + 1) * 3) / 4;
52 dc
= dg
- (c
* 36524);
55 a
= (((db
/ 365) + 1) * 3) / 4;
57 y
= (g
* 400) + (c
* 100) + (b
* 4) + a
;
58 m
= (((da
* 5) + 308) / 153) - 2;
59 d
= da
- (((m
+ 4) * 153) / 5) + 122;
61 Time
->Year
= (UINT16
)(y
- 4800 + ((m
+ 2) / 12));
62 Time
->Month
= ((m
+ 2) % 12) + 1;
63 Time
->Day
= (UINT8
)(d
+ 1);
65 ss
= EpochSeconds
% 60;
66 a
= (EpochSeconds
- ss
) / 60;
71 Time
->Hour
= (UINT8
)hh
;
72 Time
->Minute
= (UINT8
)mm
;
73 Time
->Second
= (UINT8
)ss
;
80 @param Time The UEFI time to be calculated.
82 @return Number of days.
94 UINTN JulianDate
; // Absolute Julian Date representation of the supplied Time
95 UINTN EpochDays
; // Number of days elapsed since EPOCH_JULIAN_DAY
97 a
= (14 - Time
->Month
) / 12;
98 y
= Time
->Year
+ 4800 - a
;
99 m
= Time
->Month
+ (12*a
) - 3;
101 JulianDate
= Time
->Day
+ ((153*m
+ 2)/5) + (365*y
) + (y
/4) - (y
/100) + (y
/400) - 32045;
103 ASSERT (JulianDate
>= EPOCH_JULIAN_DATE
);
104 EpochDays
= JulianDate
- EPOCH_JULIAN_DATE
;
110 Converts EFI_TIME to Epoch seconds (elapsed since 1970 JANUARY 01, 00:00:00 UTC).
112 @param Time The UEFI time to be converted.
114 @return Number of seconds.
123 UINTN EpochDays
; // Number of days elapsed since EPOCH_JULIAN_DAY
126 EpochDays
= EfiGetEpochDays (Time
);
128 EpochSeconds
= (EpochDays
* SEC_PER_DAY
) + ((UINTN
)Time
->Hour
* SEC_PER_HOUR
) + (Time
->Minute
* SEC_PER_MIN
) + Time
->Second
;
134 Get the day of the week from the UEFI time.
136 @param Time The UEFI time to be calculated.
138 @return The day of the week: Sunday=0, Monday=1, ... Saturday=6
146 UINTN EpochDays
; // Number of days elapsed since EPOCH_JULIAN_DAY
148 EpochDays
= EfiGetEpochDays (Time
);
150 // 4=1/1/1970 was a Thursday
152 return (EpochDays
+ 4) % 7;
156 Check if it is a leap year.
158 @param Time The UEFI time to be checked.
160 @retval TRUE It is a leap year.
161 @retval FALSE It is NOT a leap year.
170 if (Time
->Year
% 4 == 0) {
171 if (Time
->Year
% 100 == 0) {
172 if (Time
->Year
% 400 == 0) {
186 Check if the day in the UEFI time is valid.
188 @param Time The UEFI time to be checked.
191 @retval FALSE Invalid.
200 STATIC CONST INTN DayOfMonth
[12] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
202 if ((Time
->Day
< 1) ||
203 (Time
->Day
> DayOfMonth
[Time
->Month
- 1]) ||
204 ((Time
->Month
== 2) && (!IsLeapYear (Time
) && (Time
->Day
> 28)))
214 Check if the time zone is valid.
215 Valid values are between -1440 and 1440 or 2047 (EFI_UNSPECIFIED_TIMEZONE).
217 @param TimeZone The time zone to be checked.
220 @retval FALSE Invalid.
229 return TimeZone
== EFI_UNSPECIFIED_TIMEZONE
||
230 (TimeZone
>= -1440 && TimeZone
<= 1440);
234 Check if the daylight is valid.
236 0 : Time is not affected.
237 1 : Time is affected, and has not been adjusted for daylight savings.
238 3 : Time is affected, and has been adjusted for daylight savings.
239 All other values are invalid.
241 @param Daylight The daylight to be checked.
244 @retval FALSE Invalid.
253 return Daylight
== 0 ||
254 Daylight
== EFI_TIME_ADJUST_DAYLIGHT
||
255 Daylight
== (EFI_TIME_ADJUST_DAYLIGHT
| EFI_TIME_IN_DAYLIGHT
);
259 Check if the UEFI time is valid.
261 @param Time The UEFI time to be checked.
264 @retval FALSE Invalid.
273 // Check the input parameters are within the range specified by UEFI
274 if ((Time
->Year
< 2000) ||
275 (Time
->Year
> 2099) ||
277 (Time
->Month
> 12) ||
278 (!IsDayValid (Time
)) ||
280 (Time
->Minute
> 59) ||
281 (Time
->Second
> 59) ||
282 (Time
->Nanosecond
> 999999999) ||
283 (!IsValidTimeZone (Time
->TimeZone
)) ||
284 (!IsValidDaylight (Time
->Daylight
)))