+STATIC\r
+BOOLEAN\r
+IsValidDaylight (\r
+ IN INT8 Daylight\r
+ )\r
+{\r
+ return Daylight == 0 ||\r
+ Daylight == EFI_TIME_ADJUST_DAYLIGHT ||\r
+ Daylight == (EFI_TIME_ADJUST_DAYLIGHT | EFI_TIME_IN_DAYLIGHT);\r
+}\r
+\r
+STATIC\r
+BOOLEAN\r
+EFIAPI\r
+IsLeapYear (\r
+ IN EFI_TIME *Time\r
+ )\r
+{\r
+ if (Time->Year % 4 == 0) {\r
+ if (Time->Year % 100 == 0) {\r
+ if (Time->Year % 400 == 0) {\r
+ return TRUE;\r
+ } else {\r
+ return FALSE;\r
+ }\r
+ } else {\r
+ return TRUE;\r
+ }\r
+ } else {\r
+ return FALSE;\r
+ }\r
+}\r
+\r
+STATIC CONST INTN mDayOfMonth[12] = {\r
+ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31\r
+};\r
+\r
+STATIC\r
+BOOLEAN\r
+EFIAPI\r
+IsDayValid (\r
+ IN EFI_TIME *Time\r
+ )\r
+{\r
+ ASSERT (Time->Day >= 1);\r
+ ASSERT (Time->Day <= mDayOfMonth[Time->Month - 1]);\r
+ ASSERT (Time->Month != 2 || IsLeapYear (Time) || Time->Day <= 28);\r
+\r
+ if (Time->Day < 1 ||\r
+ Time->Day > mDayOfMonth[Time->Month - 1] ||\r
+ (Time->Month == 2 && !IsLeapYear (Time) && Time->Day > 28)) {\r
+ return FALSE;\r
+ }\r
+ return TRUE;\r
+}\r
+\r
+STATIC\r
+BOOLEAN\r
+EFIAPI\r
+IsTimeValid(\r
+ IN EFI_TIME *Time\r
+ )\r
+{\r
+ // Check the input parameters are within the range specified by UEFI\r
+ if (Time->Year < 1900 ||\r
+ Time->Year > 9999 ||\r
+ Time->Month < 1 ||\r
+ Time->Month > 12 ||\r
+ !IsDayValid (Time) ||\r
+ Time->Hour > 23 ||\r
+ Time->Minute > 59 ||\r
+ Time->Second > 59 ||\r
+ !IsValidTimeZone (Time->TimeZone) ||\r
+ !IsValidDaylight (Time->Daylight)) {\r
+ return FALSE;\r
+ }\r
+ return TRUE;\r
+}\r