Since function timegm() is calculating the wrong value for the number of seconds since 1/1/1970,
I copied the source to my project and renamed it, and made a few tweeks. You'll notice that the
first original calculation is suppose to calculate the number of seconds in the years since 1970.
But it loads the value into ttDays, instead of ttYears as I would have expected. Then two calcs
later under comment "Extract time_t seconds from tm_mon" it calculates the number of seconds in
the months of the current year and overwrites the first calculation for years. Looks suspicious
to me.
After my changes, it now comes very close to the actual time. It's off by an hour when using time(),
but that may be the leap-year issue. And off by 7 hours when using localtime() (UTC setting?).
In any case, at least it's in the ballpark now. I compared the same function in v2.8.1 with the
one in v2.8.3, and they appear to be the same, so I can't explain why v2.8.1 works and v2.8.3 doesn't.
Maybe someone who knows more about this than me can shed some light on it.
Code: Select all
time_t mytimegm(struct tm *bts)
{
time_t ttYears = 0; // Seconds converted from tm_year (since 1900)
time_t ttMonths = 0; // Seconds converted from tm_mon (0-11)
time_t ttDays = 0; // Seconds converted from tm_mday (1-31)
time_t ttHours = 0; // Seconds converted from tm_hour (0-23)
time_t ttMinutes = 0; // Seconds converted from tm_min (0-59)
time_t ttSecs = 0; // Cumulative seconds including tm_sec (0-59)
time_t numYears=0;
int daysPerMonth[] = { 31 /* Jan */, 28 /* Feb */, 31 /* Mar */,
30 /* Apr */, 31 /* May */, 30 /* Jun */,
31 /* Jul */, 31 /* Aug */, 30 /* Sep */,
31 /* Oct */, 30 /* Nov */, 31 /* Dec */ };
// Extract time_t seconds from tm_year (time_t starts from 1970-01-01)
#ifdef foo
if(bts->tm_year<69)
ttDays -= (((69-bts->tm_year)+3) / 4) * 24 * 3600;
else
ttDays += (((bts->tm_year - 69)) / 4) * 24 * 3600; // Add leap days excluding current year
#else
numYears = (bts->tm_year+1900) - 1970;
ttYears = numYears * 365 * 86400; // Calc seconds of years since 1970.
ttYears += (numYears / 4) * 86400; // Add a day of sec for each leap year.
#endif
// Extract time_t seconds from tm_mon
for (int i = 0; i < bts->tm_mon; i++ ) { ttMonths += daysPerMonth[i]; }
ttMonths *= 24 * 3600;
// Extract time_t seconds from tm_mday
ttDays = (bts->tm_mday - 1) * 24 * 3600;
#ifdef foo
ttDays += ((bts->tm_year - 70) / 4) * 24 * 3600; // Add leap days excluding current year
#endif
// Extract time_t seconds from tm_hour
ttHours = bts->tm_hour * 3600;
// Extract time_t seconds from tm_min
ttMinutes = bts->tm_min * 60;
// Tally up extracted seconds including tm_sec
ttSecs = bts->tm_sec + ttMinutes + ttHours + ttDays + ttMonths + ttYears;
iprintf("Sec: %d, Min: %ld, Hrs: %ld, Days: %ld, Mon: %ld, Yrs: %ld\r\n",
bts->tm_sec, ttMinutes, ttHours, ttDays, ttMonths, ttYears );
// Determine if current leap year and add add leap day if necessary
if (((bts->tm_year % 4) == 0) && (bts->tm_mon > 1)) {
ttSecs += 24 * 3600;
}
return ttSecs;
}