MCPcopy Create free account
hub / github.com/eggert/tz / timesub

Function timesub

localtime.c:2331–2443  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

2329}
2330
2331static struct tm *
2332timesub(const time_t *timep, int_fast32_t offset,
2333 const struct state *sp, struct tm *tmp)
2334{
2335 register time_t tdays;
2336 register const int * ip;
2337 int_fast32_2s corr;
2338 register int i;
2339 int_fast32_t idays, rem, dayoff, dayrem;
2340 time_t y;
2341
2342 /* If less than SECSPERMIN, the number of seconds since the
2343 most recent positive leap second; otherwise, do not add 1
2344 to localtime tm_sec because of leap seconds. */
2345 time_t secs_since_posleap = SECSPERMIN;
2346
2347 corr = 0;
2348 i = sp ? leapcount(sp) : 0;
2349 while (--i >= 0) {
2350 struct lsinfo ls = lsinfo(sp, i);
2351 if (ls.ls_trans <= *timep) {
2352 corr = ls.ls_corr;
2353 if ((i == 0 ? 0 : lsinfo(sp, i - 1).ls_corr) < corr)
2354 secs_since_posleap = *timep - ls.ls_trans;
2355 break;
2356 }
2357 }
2358
2359 /* Calculate the year, avoiding integer overflow even if
2360 time_t is unsigned. */
2361 tdays = *timep / SECSPERDAY;
2362 rem = *timep % SECSPERDAY;
2363 rem += offset % SECSPERDAY - corr % SECSPERDAY + 3 * SECSPERDAY;
2364 dayoff = offset / SECSPERDAY - corr / SECSPERDAY + rem / SECSPERDAY - 3;
2365 rem %= SECSPERDAY;
2366 /* y = (EPOCH_YEAR
2367 + floor((tdays + dayoff) / DAYSPERREPEAT) * YEARSPERREPEAT),
2368 sans overflow. But calculate against 1570 (EPOCH_YEAR -
2369 YEARSPERREPEAT) instead of against 1970 so that things work
2370 for localtime values before 1970 when time_t is unsigned. */
2371 dayrem = tdays % DAYSPERREPEAT;
2372 dayrem += dayoff % DAYSPERREPEAT;
2373 y = (EPOCH_YEAR - YEARSPERREPEAT
2374 + ((1 + dayoff / DAYSPERREPEAT + dayrem / DAYSPERREPEAT
2375 - ((dayrem % DAYSPERREPEAT) < 0)
2376 + tdays / DAYSPERREPEAT)
2377 * YEARSPERREPEAT));
2378 /* idays = (tdays + dayoff) mod DAYSPERREPEAT, sans overflow. */
2379 idays = tdays % DAYSPERREPEAT;
2380 idays += dayoff % DAYSPERREPEAT + 2 * DAYSPERREPEAT;
2381 idays %= DAYSPERREPEAT;
2382 /* Increase Y and decrease IDAYS until IDAYS is in range for Y. */
2383 while (year_lengths[isleap(y)] <= idays) {
2384 int tdelta = idays / DAYSPERLYEAR;
2385 int_fast32_t ydelta = tdelta + !tdelta;
2386 time_t newy = y + ydelta;
2387 register int leapdays;
2388 leapdays = leaps_thru_end_of(newy - 1) -

Callers 2

localsubFunction · 0.85
localtime.cFile · 0.85

Calls 3

leapcountFunction · 0.85
leaps_thru_end_ofFunction · 0.85
lsinfoClass · 0.70

Tested by

no test coverage detected