static void YMD_TO_TM(const YMD *ymd, struct tm *time, bool *leap_added) { time->tm_year = NormalizeYMDYear(ymd->year); time->tm_mon = ymd->mon; time->tm_wday = ymd->wday; time->tm_mday = ymd->mday; int t = ymd->time; t /= DateTimeTicks_PerSecond; // discard ms time->tm_sec = t % 60; t /= 60; time->tm_min = t % 60; t /= 60; time->tm_hour = t; // mktime etc. broken-out time accepts 1900 as a start year while epoch is 1970 // temporarily add a calendar day for leap pass bool leap_year = IsLeap(time->tm_year); *leap_added = false; if (ymd->yday == 60 && leap_year) { time->tm_mday++; *leap_added = true; } }
STATIC EFI_STATUS GetUTCTime(OUT EFI_TIME *Timestamp) { EFI_STATUS Status; UINTN Timer = 0; UINTN Year, YearNo, MonthNo; UINTN DayNo, DayRemainder; if (Timestamp == NULL) { return EFI_INVALID_PARAMETER; } // Get current time Status = gRT->GetTime(Timestamp, NULL); if (EFI_ERROR(Status)) { return Status; } // Get the current offset of the year in seconds since epoch for (Year = 1970; Year < Timestamp->Year; ++Year) { Timer += (UINTN)((IsLeap (Year) ? 366 : 365) * SECSPERDAY); } // Get the current offset Timer += (UINTN)((Timestamp->TimeZone != EFI_UNSPECIFIED_TIMEZONE) ? (Timestamp->TimeZone * 60) : 0) + (UINTN)(CumulativeDays[IsLeap(Timestamp->Year)][Timestamp->Month] * SECSPERDAY) + (UINTN)(((Timestamp->Day > 0) ? Timestamp->Day - 1 : 0) * SECSPERDAY) + (UINTN)(Timestamp->Hour * SECSPERHOUR) + (UINTN)(Timestamp->Minute * 60) + (UINTN)Timestamp->Second; // Convert back to time ZeroMem(Timestamp, sizeof(EFI_TIME)); DayNo = (UINTN)(Timer / SECSPERDAY); DayRemainder = (UINTN)(Timer % SECSPERDAY); Timestamp->Second = (UINT8)(DayRemainder % SECSPERMIN); Timestamp->Minute = (UINT8)((DayRemainder % SECSPERHOUR) / SECSPERMIN); Timestamp->Hour = (UINT8)(DayRemainder / SECSPERHOUR); for (Year = 1970, YearNo = 0; DayNo > 0; ++Year) { UINTN TotalDays = (IsLeap(Year) ? 366 : 365); if (DayNo >= TotalDays) { DayNo = (DayNo - TotalDays); YearNo++; } else { break; } } Timestamp->Year = (UINT16)(YearNo + 1970); for (MonthNo = 12; MonthNo > 1; --MonthNo) { if (DayNo >= CumulativeDays[IsLeap(Year)][MonthNo]) { DayNo = (UINT16) (DayNo - (UINT16) (CumulativeDays[IsLeap(Year)][MonthNo])); break; } } Timestamp->Month = (UINT8)MonthNo; Timestamp->Day = (UINT8)(DayNo + 1); Timestamp->Nanosecond = 0; Timestamp->TimeZone = 0; Timestamp->Daylight = 0; Timestamp->Pad1 = 0; Timestamp->Pad2 = 0; return EFI_SUCCESS; }
int DaysInMonth(int month, int year) { int days[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; if(month < 1 || month > 12) return(-1); if(month == 2 && IsLeap(year)) return(29); return days[month-1]; }
uint8 TIME_AddDate(uint8 *pDate, uint8 date) //日增量 { uint8 year1; uint8 month1; uint8 day1; uint8 days[13]; year1 = BcdToHex(pDate[5]); month1 = BcdToHex(pDate[4]); day1 = BcdToHex(pDate[3]); days[0] = 0; days[1] = 31; days[2] = 28; days[3] = 31; days[4] = 30; days[5] = 31; days[6] = 30; days[7] = 31; days[8] = 31; days[9] = 30; days[10] = 31; days[11] = 30; days[12] = 31; if( (!IsLeap(year1) || month1 != 2)) { if ((day1 + date) <= days[month1] ) { pDate[3] = HexToBcd(day1 + date); pDate[4] = HexToBcd(month1); pDate[5] = HexToBcd(year1); } else { pDate[3] = HexToBcd(day1 + date - days[month1]); if (month1 == 12) { pDate[5] = HexToBcd(year1 + 1); pDate[4] = 1; } else { pDate[5] = HexToBcd(year1); pDate[4] = HexToBcd(month1 + 1); } } } else { if ((day1 + date) < 29) { pDate[3] = HexToBcd(day1 + date); pDate[4] = 2; pDate[5] = HexToBcd(year1); } else { pDate[3] = HexToBcd(day1 + date - 29); pDate[4] = 3; pDate[5] = HexToBcd(year1); } } return 0; }