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