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