This patch add function EfiTimeToWday() which returns day of the week. It is needed by our upcoming patches in edk2-platforms. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Vabhav Sharma <vabhav.sharma@nxp.com> Signed-off-by: Meenakshi Aggarwal <meenakshi.aggarwal@nxp.com> Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
		
			
				
	
	
		
			204 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			204 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @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;
 | |
| 
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Calculate Epoch days
 | |
|  **/
 | |
| UINTN
 | |
| EFIAPI
 | |
| EfiGetEpochDays (
 | |
|   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
 | |
| 
 | |
|   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;
 | |
| 
 | |
|   return EpochDays;
 | |
| }
 | |
| /**
 | |
|   Converts EFI_TIME to Epoch seconds (elapsed since 1970 JANUARY 01, 00:00:00 UTC)
 | |
|  **/
 | |
| UINTN
 | |
| EFIAPI
 | |
| EfiTimeToEpoch (
 | |
|   IN  EFI_TIME  *Time
 | |
|   )
 | |
| {
 | |
|   UINTN EpochDays;   // Number of days elapsed since EPOCH_JULIAN_DAY
 | |
|   UINTN EpochSeconds;
 | |
| 
 | |
|   EpochDays = EfiGetEpochDays (Time);
 | |
| 
 | |
|   EpochSeconds = (EpochDays * SEC_PER_DAY) + ((UINTN)Time->Hour * SEC_PER_HOUR) + (Time->Minute * SEC_PER_MIN) + Time->Second;
 | |
| 
 | |
|   return EpochSeconds;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   returns Day of the week [0-6] 0=Sunday
 | |
|  **/
 | |
| UINTN
 | |
| EfiTimeToWday (
 | |
|   IN  EFI_TIME  *Time
 | |
|   )
 | |
| {
 | |
|   UINTN EpochDays;   // Number of days elapsed since EPOCH_JULIAN_DAY
 | |
| 
 | |
|   EpochDays = EfiGetEpochDays (Time);
 | |
| 
 | |
|   // 4=1/1/1970 was a Thursday
 | |
| 
 | |
|   return (EpochDays + 4) % 7;
 | |
| }
 | |
| 
 | |
| 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;
 | |
| }
 |