/** @file | |
* | |
* Copyright (c) 2016, Hisilicon Limited. All rights reserved. | |
* Copyright (c) 2016, Linaro Limited. All rights reserved. | |
* | |
* This program and the accompanying materials | |
* are licensed and made available under the terms and conditions of the BSD License | |
* which accompanies this distribution. The full text of the license may be found at | |
* http://opensource.org/licenses/bsd-license.php | |
* | |
* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, | |
* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. | |
* | |
**/ | |
#include <Uefi/UefiBaseType.h> | |
#include <Uefi/UefiSpec.h> | |
#include <Library/DebugLib.h> | |
#include <Library/TimeBaseLib.h> | |
/** | |
Converts Epoch seconds (elapsed since 1970 JANUARY 01, 00:00:00 UTC) to EFI_TIME | |
**/ | |
VOID | |
EFIAPI | |
EpochToEfiTime ( | |
IN UINTN EpochSeconds, | |
OUT EFI_TIME *Time | |
) | |
{ | |
UINTN a; | |
UINTN b; | |
UINTN c; | |
UINTN d; | |
UINTN g; | |
UINTN j; | |
UINTN m; | |
UINTN y; | |
UINTN da; | |
UINTN db; | |
UINTN dc; | |
UINTN dg; | |
UINTN hh; | |
UINTN mm; | |
UINTN ss; | |
UINTN J; | |
J = (EpochSeconds / 86400) + 2440588; | |
j = J + 32044; | |
g = j / 146097; | |
dg = j % 146097; | |
c = (((dg / 36524) + 1) * 3) / 4; | |
dc = dg - (c * 36524); | |
b = dc / 1461; | |
db = dc % 1461; | |
a = (((db / 365) + 1) * 3) / 4; | |
da = db - (a * 365); | |
y = (g * 400) + (c * 100) + (b * 4) + a; | |
m = (((da * 5) + 308) / 153) - 2; | |
d = da - (((m + 4) * 153) / 5) + 122; | |
Time->Year = y - 4800 + ((m + 2) / 12); | |
Time->Month = ((m + 2) % 12) + 1; | |
Time->Day = d + 1; | |
ss = EpochSeconds % 60; | |
a = (EpochSeconds - ss) / 60; | |
mm = a % 60; | |
b = (a - mm) / 60; | |
hh = b % 24; | |
Time->Hour = hh; | |
Time->Minute = mm; | |
Time->Second = ss; | |
Time->Nanosecond = 0; | |
} | |
/** | |
Converts EFI_TIME to Epoch seconds (elapsed since 1970 JANUARY 01, 00:00:00 UTC) | |
**/ | |
UINTN | |
EFIAPI | |
EfiTimeToEpoch ( | |
IN EFI_TIME *Time | |
) | |
{ | |
UINTN a; | |
UINTN y; | |
UINTN m; | |
UINTN JulianDate; // Absolute Julian Date representation of the supplied Time | |
UINTN EpochDays; // Number of days elapsed since EPOCH_JULIAN_DAY | |
UINTN EpochSeconds; | |
a = (14 - Time->Month) / 12 ; | |
y = Time->Year + 4800 - a; | |
m = Time->Month + (12*a) - 3; | |
JulianDate = Time->Day + ((153*m + 2)/5) + (365*y) + (y/4) - (y/100) + (y/400) - 32045; | |
ASSERT (JulianDate >= EPOCH_JULIAN_DATE); | |
EpochDays = JulianDate - EPOCH_JULIAN_DATE; | |
EpochSeconds = (EpochDays * SEC_PER_DAY) + ((UINTN)Time->Hour * SEC_PER_HOUR) + (Time->Minute * SEC_PER_MIN) + Time->Second; | |
return EpochSeconds; | |
} | |
BOOLEAN | |
EFIAPI | |
IsLeapYear ( | |
IN EFI_TIME *Time | |
) | |
{ | |
if (Time->Year % 4 == 0) { | |
if (Time->Year % 100 == 0) { | |
if (Time->Year % 400 == 0) { | |
return TRUE; | |
} else { | |
return FALSE; | |
} | |
} else { | |
return TRUE; | |
} | |
} else { | |
return FALSE; | |
} | |
} | |
BOOLEAN | |
EFIAPI | |
IsDayValid ( | |
IN EFI_TIME *Time | |
) | |
{ | |
STATIC CONST INTN DayOfMonth[12] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; | |
if (Time->Day < 1 || | |
Time->Day > DayOfMonth[Time->Month - 1] || | |
(Time->Month == 2 && (!IsLeapYear (Time) && Time->Day > 28)) | |
) { | |
return FALSE; | |
} | |
return TRUE; | |
} | |
BOOLEAN | |
EFIAPI | |
IsTimeValid( | |
IN EFI_TIME *Time | |
) | |
{ | |
// Check the input parameters are within the range specified by UEFI | |
if ((Time->Year < 2000) || | |
(Time->Year > 2099) || | |
(Time->Month < 1 ) || | |
(Time->Month > 12 ) || | |
(!IsDayValid (Time) ) || | |
(Time->Hour > 23 ) || | |
(Time->Minute > 59 ) || | |
(Time->Second > 59 ) || | |
(Time->Nanosecond > 999999999) || | |
(!((Time->TimeZone == EFI_UNSPECIFIED_TIMEZONE) || ((Time->TimeZone >= -1440) && (Time->TimeZone <= 1440)))) || | |
(Time->Daylight & (~(EFI_TIME_ADJUST_DAYLIGHT | EFI_TIME_IN_DAYLIGHT))) | |
) { | |
return FALSE; | |
} | |
return TRUE; | |
} |