amiga-tz/library/time_time2posix.c

100 lines
1.8 KiB
C

#include "time_header.h"
/*
* IEEE Std 1003.1-1988 (POSIX) legislates that 536457599
* shall correspond to "Wed Dec 31 23:59:59 UTC 1986", which
* is not the case if we are accounting for leap seconds.
* So, we provide the following conversion routines for use
* when exchanging timestamps with POSIX conforming systems.
*
*/
static int_fast64_t
leapcorr(struct state const *sp, time_t t)
{
register struct lsinfo const *lp;
register int i;
i = sp->leapcnt;
while (--i >= 0) {
lp = &sp->lsis[i];
if (t >= lp->ls_trans)
return lp->ls_corr;
}
return 0;
}
time_t time2posix_z(struct state *sp, time_t t)
{
return t - leapcorr(sp, t);
}
time_t time2posix(time_t t)
{
int err = lock();
if (err) {
errno = err;
return -1;
}
if (!lcl_is_set)
tzset_unlocked();
if (lclptr)
t = time2posix_z(lclptr, t);
unlock();
return t;
}
time_t posix2time_z(struct state *sp, time_t t)
{
time_t x;
time_t y;
/*
** For a positive leap second hit, the result
** is not unique. For a negative leap second
** hit, the corresponding time doesn't exist,
** so we return an adjacent second.
*/
x = t + leapcorr(sp, t);
y = x - leapcorr(sp, x);
if (y < t) {
do {
x++;
y = x - leapcorr(sp, x);
} while (y < t);
x -= y != t;
} else if (y > t) {
do {
--x;
y = x - leapcorr(sp, x);
} while (y > t);
x += y != t;
}
return x;
}
time_t posix2time(time_t t)
{
int err = lock();
if (err) {
errno = err;
return -1;
}
if (!lcl_is_set)
tzset_unlocked();
if (lclptr)
t = posix2time_z(lclptr, t);
unlock();
return t;
}