GIntBig CPLYMDHMSToUnixTime(const struct tm *brokendowntime) { GIntBig days; int mon; if (brokendowntime->tm_mon < 0 || brokendowntime->tm_mon >= 12) return -1; /* Number of days of the current month */ days = brokendowntime->tm_mday - 1; /* Add the number of days of the current year */ const int* ip = mon_lengths[isleap(TM_YEAR_BASE + brokendowntime->tm_year)]; for(mon=0;mon<brokendowntime->tm_mon;mon++) days += ip [mon]; /* Add the number of days of the other years */ days += (TM_YEAR_BASE + (GIntBig)brokendowntime->tm_year - EPOCH_YEAR) * DAYSPERNYEAR + LEAPS_THRU_END_OF(TM_YEAR_BASE + (GIntBig)brokendowntime->tm_year - 1) - LEAPS_THRU_END_OF(EPOCH_YEAR - 1); /* Now add the secondes, minutes and hours to the number of days since EPOCH */ return brokendowntime->tm_sec + brokendowntime->tm_min * SECSPERMIN + brokendowntime->tm_hour * SECSPERHOUR + days * SECSPERDAY; }
VOID fsw_efi_decode_time(OUT EFI_TIME *EfiTime, IN UINT32 UnixTime) { long days, rem; int y, newy, yleap; const int *ip; ZeroMem(EfiTime, sizeof(EFI_TIME)); days = UnixTime / SECSPERDAY; rem = UnixTime % SECSPERDAY; EfiTime->Hour = (UINT8) (rem / SECSPERHOUR); rem = rem % SECSPERHOUR; EfiTime->Minute = (UINT8) (rem / SECSPERMIN); EfiTime->Second = (UINT8) (rem % SECSPERMIN); y = EPOCH_YEAR; while (days < 0 || days >= (long) year_lengths[yleap = isleap(y)]) { newy = y + days / DAYSPERNYEAR; if (days < 0) --newy; days -= (newy - y) * DAYSPERNYEAR + LEAPS_THRU_END_OF(newy - 1) - LEAPS_THRU_END_OF(y - 1); y = newy; } EfiTime->Year = (UINT16)y; ip = mon_lengths[yleap]; for (EfiTime->Month = 0; days >= (long) ip[EfiTime->Month]; ++(EfiTime->Month)) days = days - (long) ip[EfiTime->Month]; EfiTime->Month++; // adjust range to EFI conventions EfiTime->Day = (UINT8) (days + 1); }
/* Compute the `struct tm' representation of *T, offset OFFSET seconds east of UTC, and store year, yday, mon, mday, wday, hour, min, sec into *TP. Return nonzero if successful. */ int __offtime (const time_t *t, long int offset, struct tm *tp) { time_t days, rem, y; const unsigned short int *ip; days = *t / SECS_PER_DAY; rem = *t % SECS_PER_DAY; rem += offset; while (rem < 0) { rem += SECS_PER_DAY; --days; } while (rem >= SECS_PER_DAY) { rem -= SECS_PER_DAY; ++days; } tp->tm_hour = rem / SECS_PER_HOUR; rem %= SECS_PER_HOUR; tp->tm_min = rem / 60; tp->tm_sec = rem % 60; /* January 1, 1970 was a Thursday. */ tp->tm_wday = (4 + days) % 7; if (tp->tm_wday < 0) tp->tm_wday += 7; y = 1970; #define DIV(a, b) ((a) / (b) - ((a) % (b) < 0)) #define LEAPS_THRU_END_OF(y) (DIV (y, 4) - DIV (y, 100) + DIV (y, 400)) while (days < 0 || days >= (__isleap (y) ? 366 : 365)) { /* Guess a corrected year, assuming 365 days per year. */ time_t yg = y + days / 365 - (days % 365 < 0); /* Adjust DAYS and Y to match the guessed year. */ days -= ((yg - y) * 365 + LEAPS_THRU_END_OF (yg - 1) - LEAPS_THRU_END_OF (y - 1)); y = yg; } tp->tm_year = y - 1900; if (tp->tm_year != y - 1900) { /* The year cannot be represented due to overflow. */ __set_errno (EOVERFLOW); return 0; } tp->tm_yday = days; ip = __mon_yday[__isleap(y)]; for (y = 11; days < (long int) ip[y]; --y) continue; days -= ip[y]; tp->tm_mon = y; tp->tm_mday = days + 1; return 1; }
/** * Convert UNIX timestamp to date/time * Based on code from GNU C Library */ void date_from_timestamp(uint32_t timestamp, DateTimeT *date_time) { uint16_t y; int16_t days; uint32_t rem; days = timestamp / SECS_PER_DAY; rem = timestamp % SECS_PER_DAY; while (rem < 0) { rem += SECS_PER_DAY; --days; } while (rem >= SECS_PER_DAY) { rem -= SECS_PER_DAY; ++days; } date_time->hour = rem / SECS_PER_HOUR; rem %= SECS_PER_HOUR; date_time->min = rem / 60; date_time->sec = rem % 60; /* January 1, 1970 was a Thursday. */ date_time->wday = (4 + days) % 7; if (date_time->wday < 0){ date_time->wday += 7; } y = 1970; #define DIV(a, b) ((a) / (b) - ((a) % (b) < 0)) #define LEAPS_THRU_END_OF(y) (DIV (y, 4) - DIV (y, 100) + DIV (y, 400)) while (days < 0 || days >= (__isleap (y) ? 366 : 365)) { /* Guess a corrected year, assuming 365 days per year. */ uint16_t yg = y + days / 365 - (days % 365 < 0); /* Adjust DAYS and Y to match the guessed year. */ days -= ((yg - y) * 365 + LEAPS_THRU_END_OF (yg - 1) - LEAPS_THRU_END_OF (y - 1)); y = yg; } date_time->year = y - 1900; if (date_time->year != y - 1900) { /* The year cannot be represented due to overflow. */ return; } const uint16_t *ip = __mon_yday[__isleap(y)]; for (y = 11; days < (uint16_t)ip[y]; --y){ continue; } days -= ip[y]; date_time->mon = y; date_time->mday = days + 1; }
/* Compute the `struct tm' representation of *T, offset OFFSET seconds east of UTC, and store year, yday, mon, mday, wday, hour, min, sec into *TP. Return nonzero if successful. */ int offtime (unsigned long t, efi_time_t *tp) { const unsigned short int __mon_yday[2][13] = { /* Normal years. */ { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }, /* Leap years. */ { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 } }; long int days, rem, y; const unsigned short int *ip; days = t / SECS_PER_DAY; rem = t % SECS_PER_DAY; while (rem < 0) { rem += SECS_PER_DAY; --days; } while (rem >= SECS_PER_DAY) { rem -= SECS_PER_DAY; ++days; } tp->hour = rem / SECS_PER_HOUR; rem %= SECS_PER_HOUR; tp->minute = rem / 60; tp->second = rem % 60; /* January 1, 1970 was a Thursday. */ y = 1970; # define DIV(a, b) ((a) / (b) - ((a) % (b) < 0)) # define LEAPS_THRU_END_OF(y) (DIV (y, 4) - DIV (y, 100) + DIV (y, 400)) # define __isleap(year) \ ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0)) while (days < 0 || days >= (__isleap (y) ? 366 : 365)) { /* Guess a corrected year, assuming 365 days per year. */ long int yg = y + days / 365 - (days % 365 < 0); /* Adjust DAYS and Y to match the guessed year. */ days -= ((yg - y) * 365 + LEAPS_THRU_END_OF (yg - 1) - LEAPS_THRU_END_OF (y - 1)); y = yg; } tp->year = y; ip = __mon_yday[__isleap(y)]; for (y = 11; days < (long int) ip[y]; --y) continue; days -= ip[y]; tp->month = y + 1; tp->day = days + 1; return 1; }
struct tm * gmtime(const time_t *clock) { static struct tm result; struct tm *tmp; long days; int rem; long y; long newy; const int *ip; tmp = &result; days = *clock / SECS_PER_DAY; rem = *clock % SECS_PER_DAY; while (rem < 0) { rem += SECS_PER_DAY; --days; } while (rem >= SECS_PER_DAY) { rem -= SECS_PER_DAY; ++days; } tmp->tm_hour = (int)(rem / SECS_PER_HOUR); rem = rem % SECS_PER_HOUR; tmp->tm_min = (int)(rem / SECS_PER_MIN); tmp->tm_sec = (int)(rem % SECS_PER_MIN); tmp->tm_wday = (int)((EPOCH_WDAY + days) % DAYS_PER_WEEK); if (tmp->tm_wday < 0) tmp->tm_wday += DAYS_PER_WEEK; y = EPOCH_YEAR; #define LEAPS_THRU_END_OF(y) ((y) / 4 - (y) / 100 + (y) / 400) while (days < 0 || days >= (long)__year_lengths[isleap(y)]) { newy = y + days / DAYS_PER_NYEAR; if (days < 0) --newy; days -= ((long)newy - (long)y) * DAYS_PER_NYEAR + LEAPS_THRU_END_OF(newy > 0 ? newy - 1L : newy) - LEAPS_THRU_END_OF(y > 0 ? y - 1L : y); y = newy; } tmp->tm_year = y - TM_YEAR_BASE; tmp->tm_yday = days; ip = __mon_lengths[isleap(y)]; for (tmp->tm_mon = 0; days >= ip[tmp->tm_mon]; ++(tmp->tm_mon)) days = days - ip[tmp->tm_mon]; tmp->tm_mday = (days + 1); tmp->tm_isdst = 0; return (tmp); }
/** * virTimeFieldsThenRaw: * @when: the time to convert in milliseconds * @fields: filled with time @when fields * * Converts the timestamp @when into broken-down field format. * Time time is always in UTC * * Returns 0 on success, -1 on error with errno set */ int virTimeFieldsThenRaw(unsigned long long when, struct tm *fields) { /* This code is taken from GLibC under terms of LGPLv2+ */ long int days, rem, y; const unsigned short int *ip; unsigned long long whenSecs = when / 1000ull; unsigned int offset = 0; /* We hardcoded GMT */ days = whenSecs / SECS_PER_DAY; rem = whenSecs % SECS_PER_DAY; rem += offset; while (rem < 0) { rem += SECS_PER_DAY; --days; } while (rem >= SECS_PER_DAY) { rem -= SECS_PER_DAY; ++days; } fields->tm_hour = rem / SECS_PER_HOUR; rem %= SECS_PER_HOUR; fields->tm_min = rem / 60; fields->tm_sec = rem % 60; /* January 1, 1970 was a Thursday. */ fields->tm_wday = (4 + days) % 7; if (fields->tm_wday < 0) fields->tm_wday += 7; y = 1970; while (days < 0 || days >= (is_leap_year(y) ? 366 : 365)) { /* Guess a corrected year, assuming 365 days per year. */ long int yg = y + days / 365 - (days % 365 < 0); /* Adjust DAYS and Y to match the guessed year. */ days -= ((yg - y) * 365 + LEAPS_THRU_END_OF(yg - 1) - LEAPS_THRU_END_OF(y - 1)); y = yg; } fields->tm_year = y - 1900; fields->tm_yday = days; ip = __mon_yday[is_leap_year(y)]; for (y = 11; days < (long int) ip[y]; --y) continue; days -= ip[y]; fields->tm_mon = y; fields->tm_mday = days + 1; return 0; }
struct tm * myCPLUnixTimeToYMDHMS(GIntBig unixTime, struct tm* pRet) { GIntBig days = unixTime / SECSPERDAY; GIntBig rem = unixTime % SECSPERDAY; GIntBig y = EPOCH_YEAR; int yleap; const int* ip; while (rem < 0) { rem += SECSPERDAY; --days; } pRet->tm_hour = (int) (rem / SECSPERHOUR); rem = rem % SECSPERHOUR; pRet->tm_min = (int) (rem / SECSPERMIN); /* ** A positive leap second requires a special ** representation. This uses "... ??:59:60" et seq. */ pRet->tm_sec = (int) (rem % SECSPERMIN); pRet->tm_wday = (int) ((EPOCH_WDAY + days) % DAYSPERWEEK); if (pRet->tm_wday < 0) pRet->tm_wday += DAYSPERWEEK; while (days < 0 || days >= (GIntBig) year_lengths[yleap = isleap(y)]) { GIntBig newy; newy = y + days / DAYSPERNYEAR; if (days < 0) --newy; days -= (newy - y) * DAYSPERNYEAR + LEAPS_THRU_END_OF(newy - 1) - LEAPS_THRU_END_OF(y - 1); y = newy; } pRet->tm_year = (int) (y - TM_YEAR_BASE); pRet->tm_yday = (int) days; ip = mon_lengths[yleap]; for (pRet->tm_mon = 0; days >= (GIntBig) ip[pRet->tm_mon]; ++(pRet->tm_mon)) days = days - (GIntBig) ip[pRet->tm_mon]; pRet->tm_mday = (int) (days + 1); pRet->tm_isdst = 0; return pRet; }
/*Ripped from epoch2time() thc-vlogger*/ int epoch2time (const time_t *t, long int offset, struct vtm *tp) { static const unsigned short int mon_yday[2][13] = { /* Normal years. */ { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }, /* Leap years. */ { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 } }; long int days, rem, y; const unsigned short int *ip; days = *t / SECS_PER_DAY; rem = *t % SECS_PER_DAY; rem += offset; while (rem < 0) { rem += SECS_PER_DAY; --days; } while (rem >= SECS_PER_DAY) { rem -= SECS_PER_DAY; ++days; } tp->tm_hour = rem / SECS_PER_HOUR; rem %= SECS_PER_HOUR; tp->tm_min = rem / 60; tp->tm_sec = rem % 60; y = 1970; while (days < 0 || days >= (isleap (y) ? 366 : 365)) { long int yg = y + days / 365 - (days % 365 < 0); days -= ((yg - y) * 365 + LEAPS_THRU_END_OF (yg - 1) - LEAPS_THRU_END_OF (y - 1)); y = yg; } tp->tm_year = y - 1900; if (tp->tm_year != y - 1900) return 0; ip = mon_yday[isleap(y)]; for (y = 11; days < (long int) ip[y]; --y) continue; days -= ip[y]; tp->tm_mon = y; tp->tm_mday = days + 1; return 1; }
VOID NTAPI LlbConvertRtcTime(IN ULONG RtcTime, OUT TIMEINFO* TimeInfo) { ULONG Month, Year, Days, DaysLeft; /* Count the days, keep the minutes */ Days = RtcTime / 86400; RtcTime -= Days * 86400; /* Get the year, based on days since 1970 */ Year = 1970 + Days / 365; /* Account for leap years which changed the number of days/year */ Days -= (Year - 1970) * 365 + LEAPS_THRU_END_OF(Year - 1) - LEAPS_THRU_END_OF(1970 - 1); if (Days < 0) { /* We hit a leap year, so fixup the math */ Year--; Days += 365 + LlbIsLeapYear(Year); } /* Count months */ for (Month = 0; Month < 11; Month++) { /* How many days in this month? */ DaysLeft = Days - LlbDayOfMonth(Month, Year); if (DaysLeft < 0) break; /* How many days left total? */ Days = DaysLeft; } /* Write the structure */ TimeInfo->Year = Year; TimeInfo->Day = Days + 1; TimeInfo->Month = Month + 1; TimeInfo->Hour = RtcTime / 3600; RtcTime -= TimeInfo->Hour * 3600; TimeInfo->Minute = RtcTime / 60; TimeInfo->Second = RtcTime - TimeInfo->Minute * 60; }
/* * Convert seconds since 01-01-1970 00:00:00 to Gregorian date. */ static void rtc_time_to_tm(u32 time, struct rtc_time *tm) { unsigned int month, year; int days; tm->tm_value = time; days = (int)(time / 86400); time -= (unsigned int) days * 86400; /* day of the week, 1970-01-01 was a Thursday */ tm->tm_wday = (days + 4) % 7; year = (unsigned int)(1970 + days / 365); days -= (s32)((year - 1970) * 365 + LEAPS_THRU_END_OF(year - 1) - LEAPS_THRU_END_OF(1970 - 1)); if (days < 0) { year -= 1; days += 365 + is_leap_year(year); } tm->tm_year = (int)year; tm->tm_yday = days + 1; for (month = 0; month < 11; month++) { int newdays; newdays = days - rtc_month_days(month, year); if (newdays < 0) break; days = newdays; } tm->tm_mon = (int)(month) + 1; tm->tm_mday = days + 1; tm->tm_hour = (int)(time / 3600); time -= (u32)(tm->tm_hour * 3600); tm->tm_min = (int)(time / 60); tm->tm_sec = (int)((int)time - tm->tm_min * 60); tm->tm_isdst = 0; }
/** * virTimeFieldsThen: * @when: the time to convert in milliseconds * @fields: filled with time @when fields * * Converts the timestamp @when into broken-down field format. * Time time is always in UTC * */ void virTimeFieldsThen(unsigned long long when, struct tm *fields) { /* This code is taken from GLibC under terms of LGPLv2+ */ /* Remove the 'offset' or GMT manipulation since we don't care. See * commit id '3ec12898' comments regarding localtime. */ long int days, rem, y; const unsigned short int *ip; unsigned long long whenSecs = when / 1000ull; days = whenSecs / SECS_PER_DAY; rem = whenSecs % SECS_PER_DAY; fields->tm_hour = rem / SECS_PER_HOUR; rem %= SECS_PER_HOUR; fields->tm_min = rem / 60; fields->tm_sec = rem % 60; /* January 1, 1970 was a Thursday. */ fields->tm_wday = (4 + days) % 7; if (fields->tm_wday < 0) fields->tm_wday += 7; y = 1970; while (days < 0 || days >= (is_leap_year(y) ? 366 : 365)) { /* Guess a corrected year, assuming 365 days per year. */ long int yg = y + days / 365 - (days % 365 < 0); /* Adjust DAYS and Y to match the guessed year. */ days -= ((yg - y) * 365 + LEAPS_THRU_END_OF(yg - 1) - LEAPS_THRU_END_OF(y - 1)); y = yg; } fields->tm_year = y - 1900; fields->tm_yday = days; ip = mon_yday[is_leap_year(y)]; for (y = 11; days < (long int) ip[y]; --y) continue; days -= ip[y]; fields->tm_mon = y; fields->tm_mday = days + 1; }
static void decodetime (unsigned long t, struct rtc_time *tval) { long days, month, year, rem; days = t / 86400; rem = t % 86400; tval->tm_hour = rem / 3600; rem %= 3600; tval->tm_min = rem / 60; tval->tm_sec = rem % 60; tval->tm_wday = (4 + days) % 7; #define LEAPS_THRU_END_OF(y) ((y)/4 - (y)/100 + (y)/400) year = 1970 + days / 365; days -= ((year - 1970) * 365 + LEAPS_THRU_END_OF (year - 1) - LEAPS_THRU_END_OF (1970 - 1)); if (days < 0) { year -= 1; days += 365 + is_leap(year); } tval->tm_year = year - 1900; tval->tm_yday = days + 1; month = 0; if (days >= 31) { days -= 31; month++; if (days >= (28 + is_leap(year))) { days -= (28 + is_leap(year)); month++; while (days >= days_in_mo[month]) { days -= days_in_mo[month]; month++; } } } tval->tm_mon = month; tval->tm_mday = days + 1; tval->tm_isdst=0; }
void rtc_time_to_tm(unsigned long time, struct rtc_time *tm) { unsigned int month, year; int days; days = time / 86400; time -= (unsigned int) days * 86400; tm->tm_wday = (days + 4) % 7; year = 1970 + days / 365; days -= (year - 1970) * 365 + LEAPS_THRU_END_OF(year - 1) - LEAPS_THRU_END_OF(1970 - 1); if (days < 0) { year -= 1; days += 365 + is_leap_year(year); } tm->tm_year = year - 1900; tm->tm_yday = days + 1; for (month = 0; month < 11; month++) { int newdays; newdays = days - rtc_month_days(month, year); if (newdays < 0) break; days = newdays; } tm->tm_mon = month; tm->tm_mday = days + 1; tm->tm_hour = time / 3600; time -= tm->tm_hour * 3600; tm->tm_min = time / 60; tm->tm_sec = time - tm->tm_min * 60; tm->tm_isdst = 0; }
/* * rtc_time64_to_tm - Converts time64_t to rtc_time. * Convert seconds since 01-01-1970 00:00:00 to Gregorian date. */ void rtc_time64_to_tm(time64_t time, struct rtc_time *tm) { unsigned int month, year, secs; int days; /* time must be positive */ days = div_s64_rem(time, 86400, &secs); /* day of the week, 1970-01-01 was a Thursday */ tm->tm_wday = (days + 4) % 7; year = 1970 + days / 365; days -= (year - 1970) * 365 + LEAPS_THRU_END_OF(year - 1) - LEAPS_THRU_END_OF(1970 - 1); while (days < 0) { year -= 1; days += 365 + is_leap_year(year); } tm->tm_year = year - 1900; tm->tm_yday = days + 1; for (month = 0; month < 11; month++) { int newdays; newdays = days - rtc_month_days(month, year); if (newdays < 0) break; days = newdays; } tm->tm_mon = month; tm->tm_mday = days + 1; tm->tm_hour = secs / 3600; secs -= tm->tm_hour * 3600; tm->tm_min = secs / 60; tm->tm_sec = secs - tm->tm_min * 60; tm->tm_isdst = 0; }
/* Compute an EFI_TIME representation of a GRUB's mtime_t */ VOID GrubTimeToEfiTime(const INT32 t, EFI_TIME *tp) { INT32 days, rem, y; const unsigned short int *ip; days = t / SECS_PER_DAY; rem = t % SECS_PER_DAY; while (rem < 0) { rem += SECS_PER_DAY; --days; } while (rem >= SECS_PER_DAY) { rem -= SECS_PER_DAY; ++days; } tp->Hour = rem / SECS_PER_HOUR; rem %= SECS_PER_HOUR; tp->Minute = rem / 60; tp->Second = rem % 60; y = 1970; while (days < 0 || days >= (__isleap (y) ? 366 : 365)) { /* Guess a corrected year, assuming 365 days per year. */ INT32 yg = y + days / 365 - (days % 365 < 0); /* Adjust DAYS and Y to match the guessed year. */ days -= ((yg - y) * 365 + LEAPS_THRU_END_OF (yg - 1) - LEAPS_THRU_END_OF (y - 1)); y = yg; } tp->Year = y; ip = __mon_yday[__isleap(y)]; for (y = 11; days < (long int) ip[y]; --y) continue; days -= ip[y]; tp->Month = y + 1; tp->Day = days + 1; }
/* * Convert seconds since 01-01-1970 00:00:00 to Gregorian date. * Added support for other years than 1970 * needed for example for Palm PDAs */ void rtc_time_to_tm(unsigned long time, struct rtc_time *tm) { register int days, month, year; days = time / 86400; time -= days * 86400; /* day of the week, 1970-01-01 was a Thursday */ /* and between 1970-01-01 and EPOCH_YEAR was EPOCH_YEAR_DAYS_DIFFERENCE days */ tm->tm_wday = (days + EPOCH_YEAR_DAYS_DIFFERENCE + 4) % 7; year = EPOCH_YEAR + days / 365; days -= (year - EPOCH_YEAR) * 365 + LEAPS_THRU_END_OF(year - 1) - LEAPS_THRU_END_OF(EPOCH_YEAR - 1); if (days < 0) { year -= 1; days += 365 + LEAP_YEAR(year); } tm->tm_year = year - 1900; tm->tm_yday = days + 1; for (month = 0; month < 11; month++) { int newdays; newdays = days - rtc_month_days(month, year); if (newdays < 0) break; days = newdays; } tm->tm_mon = month; tm->tm_mday = days + 1; tm->tm_hour = time / 3600; time -= tm->tm_hour * 3600; tm->tm_min = time / 60; tm->tm_sec = time - tm->tm_min * 60; }
/* * convert seconds since 01-01-1970 00:00:00 to gregorian date. */ void rtc_to_time(unsigned long time, struct time *tm) { u32_t month, year; s32_t days; s32_t newdays; days = time / 86400; time -= (u32_t) days * 86400; /* day of the week, 1970-01-01 was a thursday */ tm->week = (days + 4) % 7; year = 1970 + days / 365; days -= (year - 1970) * 365 + LEAPS_THRU_END_OF(year - 1) - LEAPS_THRU_END_OF(1970 - 1); if(days < 0) { year -= 1; days += 365 + LEAP_YEAR(year); } tm->year = year; tm->day = days + 1; for(month = 1; month < 12; month++) { newdays = days - rtc_month_days(year, month); if(newdays < 0) break; days = newdays; } tm->mon = month; tm->day = days + 1; tm->hour = time / 3600; time -= tm->hour * 3600; tm->min = time / 60; tm->sec = time - tm->min * 60; }
/* * Convert seconds since 01-01-1970 00:00:00 to Gregorian date. * For PMU59040, 00 in RTCY register means year 2000. */ static void rtc59040_utc_to_tm(unsigned long time, struct rtc_time *tm) { unsigned int month, year; int days; days = time / 86400; //1 day = 86400s time -= (unsigned int) days * 86400; /* day of the week, 1970-01-01 was a Thursday */ tm->tm_wday = (days + 4) % 7; year = 1970 + days / 365; days -= (year - 1970) * 365 + LEAPS_THRU_END_OF(year - 1) - LEAPS_THRU_END_OF(1970 - 1); if (days < 0) { year -= 1; days += 365 + LEAP_YEAR(year); } tm->tm_year = year - 2000; tm->tm_yday = days + 1; for (month = 0; month < 11; month++) { int newdays; newdays = days - rtc_month_days(month, year); if (newdays < 0) break; days = newdays; } tm->tm_mon = month + 1; tm->tm_mday = days + 1; tm->tm_hour = time / 3600; time -= tm->tm_hour * 3600; tm->tm_min = time / 60; tm->tm_sec = time - tm->tm_min * 60; }
static void rtc_to_time(unsigned long time, struct rtc_time_t * rt) { u32_t month, year; s32_t days; s32_t newdays; days = time / 86400; time -= (u32_t) days * 86400; rt->week = (days + 4) % 7; year = 1970 + days / 365; days -= (year - 1970) * 365 + LEAPS_THRU_END_OF(year - 1) - LEAPS_THRU_END_OF(1970 - 1); if(days < 0) { year -= 1; days += 365 + LEAP_YEAR(year); } rt->year = year; rt->day = days + 1; for(month = 1; month < 12; month++) { newdays = days - rtc_month_days(year, month); if(newdays < 0) break; days = newdays; } rt->mon = month; rt->day = days + 1; rt->hour = time / 3600; time -= rt->hour * 3600; rt->min = time / 60; rt->sec = time - rt->min * 60; }
static void timesub(const time_t *const timep, const long offset, register const struct state *const sp, register struct tm *const tmp) { register const struct lsinfo *lp; register long days; register time_t rem; register int y; register int yleap; register const int *ip; register long corr; register int hit; register int i; switch_assert(timep != NULL); switch_assert(sp != NULL); switch_assert(tmp != NULL); corr = 0; hit = 0; i = (sp == NULL) ? 0 : sp->leapcnt; while (--i >= 0) { lp = &sp->lsis[i]; if (*timep >= lp->ls_trans) { if (*timep == lp->ls_trans) { hit = ((i == 0 && lp->ls_corr > 0) || (i > 0 && lp->ls_corr > sp->lsis[i - 1].ls_corr)); if (hit) while (i > 0 && sp->lsis[i].ls_trans == sp->lsis[i - 1].ls_trans + 1 && sp->lsis[i].ls_corr == sp->lsis[i - 1].ls_corr + 1) { ++hit; --i; } } corr = lp->ls_corr; break; } } days = (long) (*timep / SECSPERDAY); rem = *timep % SECSPERDAY; #ifdef mc68k /* If this is for CPU bugs workarounds, i would remove this anyway. Who would use it on an old mc68k ? */ if (*timep == 0x80000000) { /* ** A 3B1 muffs the division on the most negative number. */ days = -24855; rem = -11648; } #endif rem += (offset - corr); while (rem < 0) { rem += SECSPERDAY; --days; } while (rem >= SECSPERDAY) { rem -= SECSPERDAY; ++days; } tmp->tm_hour = (int) (rem / SECSPERHOUR); rem = rem % SECSPERHOUR; tmp->tm_min = (int) (rem / SECSPERMIN); /* ** A positive leap second requires a special ** representation. This uses "... ??:59:60" et seq. */ tmp->tm_sec = (int) (rem % SECSPERMIN) + hit; tmp->tm_wday = (int) ((EPOCH_WDAY + days) % DAYSPERWEEK); if (tmp->tm_wday < 0) tmp->tm_wday += DAYSPERWEEK; y = EPOCH_YEAR; #define LEAPS_THRU_END_OF(y) ((y) / 4 - (y) / 100 + (y) / 400) while (days < 0 || days >= (long) year_lengths[yleap = isleap(y)]) { register int newy; newy = (int) (y + days / DAYSPERNYEAR); if (days < 0) --newy; days -= (newy - y) * DAYSPERNYEAR + LEAPS_THRU_END_OF(newy - 1) - LEAPS_THRU_END_OF(y - 1); y = newy; } tmp->tm_year = y - TM_YEAR_BASE; tmp->tm_yday = (int) days; ip = mon_lengths[yleap]; for (tmp->tm_mon = 0; days >= (long) ip[tmp->tm_mon]; ++(tmp->tm_mon)) days = days - (long) ip[tmp->tm_mon]; tmp->tm_mday = (int) (days + 1); tmp->tm_isdst = 0; #if defined(HAVE_STRUCT_TM_TM_GMTOFF) tmp->tm_gmtoff = offset; #endif }
/* Compute the `struct tm' representation of *T, offset OFFSET seconds east of UTC, and store year, yday, mon, mday, wday, hour, min, sec into *TP. Return nonzero if successful. */ bool timestamp_to_time (uint32_t timestamp, uint16_t offset, struct time_struct *tm) { const unsigned short int __mon_yday[2][13] = { /* Normal years. */ { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }, /* Leap years. */ { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 } }; uint32_t days, rem, y; const unsigned short int *ip; days = timestamp / SECS_PER_DAY; rem = timestamp % SECS_PER_DAY; rem += offset; while (rem < 0) { rem += SECS_PER_DAY; --days; } while (rem >= SECS_PER_DAY) { rem -= SECS_PER_DAY; ++days; } tm->tm_hour = rem / SECS_PER_HOUR; rem %= SECS_PER_HOUR; tm->tm_min = rem / 60; tm->tm_sec = rem % 60; /* January 1, 1970 was a Thursday. */ tm->tm_wday = (4 + days) % 7; if (tm->tm_wday < 0) tm->tm_wday += 7; y = 1970; #define DIV(a, b) ((a) / (b) - ((a) % (b) < 0)) #define LEAPS_THRU_END_OF(y) (DIV (y, 4) - DIV (y, 100) + DIV (y, 400)) while (days < 0 || days >= (__isleap (y) ? 366 : 365)) { /* Guess a corrected year, assuming 365 days per year. */ long int yg = y + days / 365 - (days % 365 < 0); /* Adjust DAYS and Y to match the guessed year. */ days -= ( (yg - y) * 365 + LEAPS_THRU_END_OF (yg - 1) - LEAPS_THRU_END_OF (y - 1)); y = yg; } tm->tm_year = y - 1900; if (tm->tm_year != y - 1900) { /* The year cannot be represented due to overflow. */ //__set_errno (EOVERFLOW); return false; } tm->tm_yday = days; ip = __mon_yday[__isleap (y) ]; for (y = 11; days < (long int) ip[y]; --y) continue; days -= ip[y]; tm->tm_mon = y; tm->tm_mday = days + 1; return true; }
static void timesub( const time_t * const timep, const long offset, const struct state * const sp, struct tm * const tmp ) { register const struct lsinfo * lp; register long days; register long rem; register int y; register int yleap; register const int * ip; register long corr; register int hit; register int i; corr = 0; hit = 0; i = sp->leapcnt; while (--i >= 0) { lp = &sp->lsis[i]; if (*timep >= lp->ls_trans) { if (*timep == lp->ls_trans) { hit = ((i == 0 && lp->ls_corr > 0) || lp->ls_corr > sp->lsis[i - 1].ls_corr); if (hit) { while (i > 0 && sp->lsis[i].ls_trans == sp->lsis[i - 1].ls_trans + 1 && sp->lsis[i].ls_corr == sp->lsis[i - 1].ls_corr + 1) { ++hit; --i; } } } corr = lp->ls_corr; break; } } days = (long)*timep / SECSPERDAY; rem = (long)*timep % SECSPERDAY; #ifdef mc68k if (*timep == 0x80000000) { /* ** A 3B1 muffs the division on the most negative number. */ days = -24855; rem = -11648; } #endif /* defined mc68k */ rem += (offset - corr); while (rem < 0) { rem += SECSPERDAY; --days; } while (rem >= SECSPERDAY) { rem -= SECSPERDAY; ++days; } tmp->tm_hour = (int) (rem / SECSPERHOUR); rem = rem % SECSPERHOUR; tmp->tm_min = (int) (rem / SECSPERMIN); /* ** A positive leap second requires a special ** representation. This uses "... ??:59:60" et seq. */ tmp->tm_sec = (int) (rem % SECSPERMIN) + hit; tmp->tm_wday = (int) ((EPOCH_WDAY + days) % DAYSPERWEEK); if (tmp->tm_wday < 0) { tmp->tm_wday += DAYSPERWEEK; } y = EPOCH_YEAR; #define LEAPS_THRU_END_OF(y) ((y) / 4 - (y) / 100 + (y) / 400) while (days < 0 || days >= (long) year_lengths[yleap = isleap(y)]) { register int newy; newy = y + days / DAYSPERNYEAR; if (days < 0) --newy; days -= (newy - y) * DAYSPERNYEAR + LEAPS_THRU_END_OF(newy - 1) - LEAPS_THRU_END_OF(y - 1); y = newy; } tmp->tm_year = y - TM_YEAR_BASE; tmp->tm_yday = (int) days; ip = mon_lengths[yleap]; for (tmp->tm_mon = 0; days >= (long) ip[tmp->tm_mon]; ++(tmp->tm_mon)) { days = days - (long) ip[tmp->tm_mon]; } tmp->tm_mday = (int) (days + 1); tmp->tm_isdst = 0; #ifdef TM_GMTOFF tmp->TM_GMTOFF = offset; #endif /* defined TM_GMTOFF */ }