1
0
mirror of https://frontier.innolan.net/rainlance/amiga-tz.git synced 2025-12-07 22:24:20 +00:00

long year work

SCCS-file: localtime.c
SCCS-SID: 7.79
This commit is contained in:
Arthur David Olson
2004-09-07 08:10:27 -04:00
committed by Paul Eggert
parent d5f287443a
commit df52193367

View File

@ -134,6 +134,9 @@ static void gmtsub P((const time_t * timep, long offset,
static void localsub P((const time_t * timep, long offset,
struct tm * tmp));
static int increment_overflow P((int * number, int delta));
static int long_increment_overflow P((long * number, int delta));
static int long_normalize_overflow P((long * tensptr,
int * unitsptr, int base));
static int normalize_overflow P((int * tensptr, int * unitsptr,
int base));
static void settzname P((void));
@ -1149,7 +1152,7 @@ register struct tm * const tmp;
register const struct lsinfo * lp;
register long days;
register long rem;
register int y;
register long y;
register int yleap;
register const int * ip;
register long corr;
@ -1218,7 +1221,7 @@ register struct tm * const tmp;
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;
register long newy;
newy = y + days / DAYSPERNYEAR;
if (days < 0)
@ -1259,6 +1262,7 @@ const time_t * const timep;
char * buf;
{
struct tm tm;
extern char * asctime_r();
return asctime_r(localtime_r(timep, &tm), buf);
}
@ -1293,6 +1297,18 @@ int delta;
return (*number < number0) != (delta < 0);
}
static int
long_increment_overflow(number, delta)
long * number;
int delta;
{
long number0;
number0 = *number;
*number += delta;
return (*number < number0) != (delta < 0);
}
static int
normalize_overflow(tensptr, unitsptr, base)
int * const tensptr;
@ -1308,6 +1324,21 @@ const int base;
return increment_overflow(tensptr, tensdelta);
}
static int
long_normalize_overflow(tensptr, unitsptr, base)
long * const tensptr;
int * const unitsptr;
const int base;
{
register int tensdelta;
tensdelta = (*unitsptr >= 0) ?
(*unitsptr / base) :
(-1 - (-1 - *unitsptr) / base);
*unitsptr -= tensdelta * base;
return long_increment_overflow(tensptr, tensdelta);
}
static int
tmcomp(atmp, btmp)
register const struct tm * const atmp;
@ -1335,8 +1366,10 @@ const int do_norm_secs;
register const struct state * sp;
register int dir;
register int bits;
register int i, j ;
register int i, j;
register int saved_seconds;
register long li;
long y;
time_t newt;
time_t t;
struct tm yourtm, mytm;
@ -1352,42 +1385,54 @@ const int do_norm_secs;
return WRONG;
if (normalize_overflow(&yourtm.tm_mday, &yourtm.tm_hour, HOURSPERDAY))
return WRONG;
if (normalize_overflow(&yourtm.tm_year, &yourtm.tm_mon, MONSPERYEAR))
y = yourtm.tm_year;
/*
** Hands off tm_year for a while.
*/
#define tm_year USE_Y_NOT_YOURTM_TM_YEAR
if (long_normalize_overflow(&y, &yourtm.tm_mon, MONSPERYEAR))
return WRONG;
/*
** Turn yourtm.tm_year into an actual year number for now.
** Turn y into an actual year number for now.
** It is converted back to an offset from TM_YEAR_BASE later.
*/
if (increment_overflow(&yourtm.tm_year, TM_YEAR_BASE))
if (long_increment_overflow(&y, TM_YEAR_BASE))
return WRONG;
while (yourtm.tm_mday <= 0) {
if (increment_overflow(&yourtm.tm_year, -1))
if (long_increment_overflow(&y, -1))
return WRONG;
i = yourtm.tm_year + (1 < yourtm.tm_mon);
yourtm.tm_mday += year_lengths[isleap(i)];
li = y + (1 < yourtm.tm_mon);
yourtm.tm_mday += year_lengths[isleap(li)];
}
while (yourtm.tm_mday > DAYSPERLYEAR) {
i = yourtm.tm_year + (1 < yourtm.tm_mon);
yourtm.tm_mday -= year_lengths[isleap(i)];
if (increment_overflow(&yourtm.tm_year, 1))
li = y + (1 < yourtm.tm_mon);
yourtm.tm_mday -= year_lengths[isleap(li)];
if (long_increment_overflow(&y, 1))
return WRONG;
}
for ( ; ; ) {
i = mon_lengths[isleap(yourtm.tm_year)][yourtm.tm_mon];
i = mon_lengths[isleap(y)][yourtm.tm_mon];
if (yourtm.tm_mday <= i)
break;
yourtm.tm_mday -= i;
if (++yourtm.tm_mon >= MONSPERYEAR) {
yourtm.tm_mon = 0;
if (increment_overflow(&yourtm.tm_year, 1))
if (long_increment_overflow(&y, 1))
return WRONG;
}
}
if (increment_overflow(&yourtm.tm_year, -TM_YEAR_BASE))
if (long_increment_overflow(&y, -TM_YEAR_BASE))
return WRONG;
/*
** Hands back on tm_year.
*/
#undef tm_year
yourtm.tm_year = y;
if (yourtm.tm_year != y)
return WRONG;
if (yourtm.tm_sec >= 0 && yourtm.tm_sec < SECSPERMIN)
saved_seconds = 0;
else if (yourtm.tm_year + TM_YEAR_BASE < EPOCH_YEAR) {
else if (y + TM_YEAR_BASE < EPOCH_YEAR) {
/*
** We can't set tm_sec to 0, because that might push the
** time below the minimum representable time.