localtime 1.78
This commit is contained in:
parent
b8aa5f7a0f
commit
0a41de2725
@ -1,4 +1,4 @@
|
|||||||
/* $NetBSD: localtime.c,v 1.77 2013/07/30 15:30:37 joerg Exp $ */
|
/* $NetBSD: localtime.c,v 1.78 2013/09/20 19:06:54 christos Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** This file is in the public domain, so clarified as of
|
** This file is in the public domain, so clarified as of
|
||||||
@ -71,6 +71,11 @@ static char privatehid[] = "@(#)private.h 7.48";
|
|||||||
#include "limits.h" /* for CHAR_BIT */
|
#include "limits.h" /* for CHAR_BIT */
|
||||||
#include "stdlib.h"
|
#include "stdlib.h"
|
||||||
#include "unistd.h" /* for F_OK and R_OK */
|
#include "unistd.h" /* for F_OK and R_OK */
|
||||||
|
#if 0
|
||||||
|
#include <assert.h>
|
||||||
|
#endif
|
||||||
|
#define time_t_min LONG_MIN
|
||||||
|
#define time_t_max LONG_MAX
|
||||||
|
|
||||||
/* Unlike <ctype.h>'s isdigit, this also works if c < 0 | c > UCHAR_MAX. */
|
/* Unlike <ctype.h>'s isdigit, this also works if c < 0 | c > UCHAR_MAX. */
|
||||||
#define is_digit(c) ((unsigned)(c) - '0' <= 9)
|
#define is_digit(c) ((unsigned)(c) - '0' <= 9)
|
||||||
@ -85,7 +90,7 @@ static char privatehid[] = "@(#)private.h 7.48";
|
|||||||
#if 0
|
#if 0
|
||||||
static char elsieid[] = "@(#)localtime.cc 8.17";
|
static char elsieid[] = "@(#)localtime.cc 8.17";
|
||||||
#else
|
#else
|
||||||
__RCSID("$NetBSD: localtime.c,v 1.77 2013/07/30 15:30:37 joerg Exp $");
|
__RCSID("$NetBSD: localtime.c,v 1.78 2013/09/20 19:06:54 christos Exp $");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -406,11 +411,11 @@ static const char gmt[] = "GMT";
|
|||||||
#endif /* !defined TZDEFDST */
|
#endif /* !defined TZDEFDST */
|
||||||
|
|
||||||
struct ttinfo { /* time type information */
|
struct ttinfo { /* time type information */
|
||||||
int_fast32_t tt_gmtoff; /* UTC offset in seconds */
|
int_fast32_t tt_gmtoff; /* UT offset in seconds */
|
||||||
int tt_isdst; /* used to set tm_isdst */
|
int tt_isdst; /* used to set tm_isdst */
|
||||||
int tt_abbrind; /* abbreviation list index */
|
int tt_abbrind; /* abbreviation list index */
|
||||||
int tt_ttisstd; /* TRUE if transition is std time */
|
int tt_ttisstd; /* TRUE if transition is std time */
|
||||||
int tt_ttisgmt; /* TRUE if transition is UTC */
|
int tt_ttisgmt; /* TRUE if transition is UT */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct lsinfo { /* leap second information */
|
struct lsinfo { /* leap second information */
|
||||||
@ -642,9 +647,8 @@ settzname (void)
|
|||||||
static int
|
static int
|
||||||
differ_by_repeat(const time_t t1, const time_t t0)
|
differ_by_repeat(const time_t t1, const time_t t0)
|
||||||
{
|
{
|
||||||
if (TYPE_INTEGRAL(time_t) &&
|
if (TYPE_BIT(time_t) - TYPE_SIGNED(time_t) < SECSPERREPEAT_BITS)
|
||||||
TYPE_BIT(time_t) - TYPE_SIGNED(time_t) < SECSPERREPEAT_BITS)
|
return 0;
|
||||||
return 0;
|
|
||||||
return (int_fast64_t)t1 - (int_fast64_t)t0 == SECSPERREPEAT;
|
return (int_fast64_t)t1 - (int_fast64_t)t0 == SECSPERREPEAT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -864,11 +868,9 @@ tzload(timezone_t sp, const char *name, const int doextend)
|
|||||||
for (i = 0; i < nread; ++i)
|
for (i = 0; i < nread; ++i)
|
||||||
up->buf[i] = p[i];
|
up->buf[i] = p[i];
|
||||||
/*
|
/*
|
||||||
** If this is a narrow integer time_t system, we're done.
|
** If this is a narrow time_t system, we're done.
|
||||||
*/
|
*/
|
||||||
if (stored >= (int) sizeof(time_t)
|
if (stored >= (int) sizeof(time_t))
|
||||||
/* CONSTCOND */
|
|
||||||
&& TYPE_INTEGRAL(time_t))
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (doextend && nread > 2 &&
|
if (doextend && nread > 2 &&
|
||||||
@ -1191,14 +1193,14 @@ getrule(const char *strp, struct rule *const rulep)
|
|||||||
** Time specified.
|
** Time specified.
|
||||||
*/
|
*/
|
||||||
++strp;
|
++strp;
|
||||||
strp = getsecs(strp, &rulep->r_time);
|
strp = getoffset(strp, &rulep->r_time);
|
||||||
} else rulep->r_time = 2 * SECSPERHOUR; /* default = 2:00:00 */
|
} else rulep->r_time = 2 * SECSPERHOUR; /* default = 2:00:00 */
|
||||||
return strp;
|
return strp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Given the Epoch-relative time of January 1, 00:00:00 UTC, in a year, the
|
** Given the Epoch-relative time of January 1, 00:00:00 UTC, in a year, the
|
||||||
** year, a rule, and the offset from UTC at the time that rule takes effect,
|
** year, a rule, and the offset from UT at the time that rule takes effect,
|
||||||
** calculate the Epoch-relative time that rule takes effect.
|
** calculate the Epoch-relative time that rule takes effect.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -1281,10 +1283,10 @@ transtime(const time_t janfirst, const int year, const struct rule *const rulep,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** "value" is the Epoch-relative time of 00:00:00 UTC on the day in
|
** "value" is the Epoch-relative time of 00:00:00 UT on the day in
|
||||||
** question. To get the Epoch-relative time of the specified local
|
** question. To get the Epoch-relative time of the specified local
|
||||||
** time on that day, add the transition time and the current offset
|
** time on that day, add the transition time and the current offset
|
||||||
** from UTC.
|
** from UT.
|
||||||
*/
|
*/
|
||||||
return (time_t)(value + rulep->r_time + offset);
|
return (time_t)(value + rulep->r_time + offset);
|
||||||
}
|
}
|
||||||
@ -1361,8 +1363,9 @@ tzparse(timezone_t sp, const char *name, const int lastditch)
|
|||||||
if (*name == ',' || *name == ';') {
|
if (*name == ',' || *name == ';') {
|
||||||
struct rule start;
|
struct rule start;
|
||||||
struct rule end;
|
struct rule end;
|
||||||
int year;
|
int year;
|
||||||
time_t janfirst;
|
int yearlim;
|
||||||
|
time_t janfirst;
|
||||||
time_t starttime;
|
time_t starttime;
|
||||||
time_t endtime;
|
time_t endtime;
|
||||||
|
|
||||||
@ -1390,33 +1393,39 @@ tzparse(timezone_t sp, const char *name, const int lastditch)
|
|||||||
typep = sp->types;
|
typep = sp->types;
|
||||||
janfirst = 0;
|
janfirst = 0;
|
||||||
sp->timecnt = 0;
|
sp->timecnt = 0;
|
||||||
for (year = EPOCH_YEAR;
|
yearlim = EPOCH_YEAR + YEARSPERREPEAT;
|
||||||
sp->timecnt + 2 <= TZ_MAX_TIMES;
|
for (year = EPOCH_YEAR; year < yearlim; year++) {
|
||||||
++year) {
|
int_fast32_t yearsecs;
|
||||||
time_t newfirst;
|
|
||||||
|
|
||||||
starttime = transtime(janfirst, year, &start,
|
starttime = transtime(janfirst, year, &start,
|
||||||
stdoffset);
|
stdoffset);
|
||||||
endtime = transtime(janfirst, year, &end,
|
endtime = transtime(janfirst, year, &end,
|
||||||
dstoffset);
|
dstoffset);
|
||||||
if (starttime > endtime) {
|
yearsecs = (year_lengths[isleap(year)]
|
||||||
*atp++ = endtime;
|
* SECSPERDAY);
|
||||||
*typep++ = 1; /* DST ends */
|
if (starttime > endtime
|
||||||
*atp++ = starttime;
|
|| (starttime < endtime
|
||||||
*typep++ = 0; /* DST begins */
|
&& (endtime - starttime
|
||||||
} else {
|
< (yearsecs
|
||||||
*atp++ = starttime;
|
+ (stdoffset - dstoffset))))) {
|
||||||
*typep++ = 0; /* DST begins */
|
if (&sp->ats[TZ_MAX_TIMES - 2] < atp)
|
||||||
*atp++ = endtime;
|
break;
|
||||||
*typep++ = 1; /* DST ends */
|
yearlim = year + YEARSPERREPEAT + 1;
|
||||||
|
if (starttime > endtime) {
|
||||||
|
*atp++ = endtime;
|
||||||
|
*typep++ = 1; /* DST ends */
|
||||||
|
*atp++ = starttime;
|
||||||
|
*typep++ = 0; /* DST begins */
|
||||||
|
} else {
|
||||||
|
*atp++ = starttime;
|
||||||
|
*typep++ = 0; /* DST begins */
|
||||||
|
*atp++ = endtime;
|
||||||
|
*typep++ = 1; /* DST ends */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
sp->timecnt += 2;
|
if (time_t_max - janfirst < yearsecs)
|
||||||
newfirst = janfirst;
|
|
||||||
newfirst += (time_t)
|
|
||||||
(year_lengths[isleap(year)] * SECSPERDAY);
|
|
||||||
if (newfirst <= janfirst)
|
|
||||||
break;
|
break;
|
||||||
janfirst = newfirst;
|
janfirst += yearsecs;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
** Get zone offsets into tzinfo (for newlib). . .
|
** Get zone offsets into tzinfo (for newlib). . .
|
||||||
@ -1428,6 +1437,10 @@ tzparse(timezone_t sp, const char *name, const int lastditch)
|
|||||||
__gettzinfo ()->__tzrule[1].offset
|
__gettzinfo ()->__tzrule[1].offset
|
||||||
= -sp->ttis[0].tt_gmtoff;
|
= -sp->ttis[0].tt_gmtoff;
|
||||||
}
|
}
|
||||||
|
//_DIAGASSERT(__type_fit(int, atp - sp->ats));
|
||||||
|
sp->timecnt = (int)(atp - sp->ats);
|
||||||
|
if (!sp->timecnt)
|
||||||
|
sp->typecnt = 1; /* Perpetual DST. */
|
||||||
} else {
|
} else {
|
||||||
int_fast32_t theirstdoffset;
|
int_fast32_t theirstdoffset;
|
||||||
int_fast32_t theirdstoffset;
|
int_fast32_t theirdstoffset;
|
||||||
@ -1759,22 +1772,14 @@ localsub(const timezone_t sp, const time_t * const timep, const int_fast32_t off
|
|||||||
(sp->goahead && t > sp->ats[sp->timecnt - 1])) {
|
(sp->goahead && t > sp->ats[sp->timecnt - 1])) {
|
||||||
time_t newt = t;
|
time_t newt = t;
|
||||||
time_t seconds;
|
time_t seconds;
|
||||||
time_t tcycles;
|
time_t years;
|
||||||
int_fast64_t icycles;
|
|
||||||
|
|
||||||
if (t < sp->ats[0])
|
if (t < sp->ats[0])
|
||||||
seconds = sp->ats[0] - t;
|
seconds = sp->ats[0] - t;
|
||||||
else seconds = t - sp->ats[sp->timecnt - 1];
|
else seconds = t - sp->ats[sp->timecnt - 1];
|
||||||
--seconds;
|
--seconds;
|
||||||
tcycles = (time_t)
|
years = (time_t)((seconds / SECSPERREPEAT + 1) * YEARSPERREPEAT);
|
||||||
(seconds / YEARSPERREPEAT / AVGSECSPERYEAR);
|
seconds = (time_t)(years * AVGSECSPERYEAR);
|
||||||
++tcycles;
|
|
||||||
icycles = tcycles;
|
|
||||||
if (tcycles - icycles >= 1 || icycles - tcycles >= 1)
|
|
||||||
return NULL;
|
|
||||||
seconds = (time_t) icycles;
|
|
||||||
seconds *= YEARSPERREPEAT;
|
|
||||||
seconds *= AVGSECSPERYEAR;
|
|
||||||
if (t < sp->ats[0])
|
if (t < sp->ats[0])
|
||||||
newt += seconds;
|
newt += seconds;
|
||||||
else newt -= seconds;
|
else newt -= seconds;
|
||||||
@ -1787,8 +1792,8 @@ localsub(const timezone_t sp, const time_t * const timep, const int_fast32_t off
|
|||||||
|
|
||||||
newy = tmp->tm_year;
|
newy = tmp->tm_year;
|
||||||
if (t < sp->ats[0])
|
if (t < sp->ats[0])
|
||||||
newy -= (time_t)icycles * YEARSPERREPEAT;
|
newy -= years;
|
||||||
else newy += (time_t)icycles * YEARSPERREPEAT;
|
else newy += years;
|
||||||
tmp->tm_year = (int)newy;
|
tmp->tm_year = (int)newy;
|
||||||
if (tmp->tm_year != newy)
|
if (tmp->tm_year != newy)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -1873,7 +1878,7 @@ gmtsub(const timezone_t sp, const time_t *const timep,
|
|||||||
#ifdef TM_ZONE
|
#ifdef TM_ZONE
|
||||||
/*
|
/*
|
||||||
** Could get fancy here and deliver something such as
|
** Could get fancy here and deliver something such as
|
||||||
** "UTC+xxxx" or "UTC-xxxx" if offset is non-zero,
|
** "UT+xxxx" or "UT-xxxx" if offset is non-zero,
|
||||||
** but this is no time for a treasure hunt.
|
** but this is no time for a treasure hunt.
|
||||||
*/
|
*/
|
||||||
if (CYGWIN_VERSION_CHECK_FOR_EXTRA_TM_MEMBERS)
|
if (CYGWIN_VERSION_CHECK_FOR_EXTRA_TM_MEMBERS)
|
||||||
@ -1997,9 +2002,10 @@ timesub(const timezone_t sp, const time_t *const timep,
|
|||||||
int leapdays;
|
int leapdays;
|
||||||
|
|
||||||
tdelta = tdays / DAYSPERLYEAR;
|
tdelta = tdays / DAYSPERLYEAR;
|
||||||
idelta = (int) tdelta;
|
if (! ((! TYPE_SIGNED(time_t) || INT_MIN <= tdelta)
|
||||||
if (tdelta - idelta >= 1 || idelta - tdelta >= 1)
|
&& tdelta <= INT_MAX))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
idelta = tdelta;
|
||||||
if (idelta == 0)
|
if (idelta == 0)
|
||||||
idelta = (tdays < 0) ? -1 : 1;
|
idelta = (tdays < 0) ? -1 : 1;
|
||||||
newy = y;
|
newy = y;
|
||||||
@ -2013,9 +2019,8 @@ timesub(const timezone_t sp, const time_t *const timep,
|
|||||||
}
|
}
|
||||||
{
|
{
|
||||||
int_fast32_t seconds;
|
int_fast32_t seconds;
|
||||||
const time_t half_second = (time_t)0.5;
|
|
||||||
|
|
||||||
seconds = (int_fast32_t)(tdays * SECSPERDAY + half_second);
|
seconds = (int_fast32_t)(tdays * SECSPERDAY);
|
||||||
tdays = (time_t)(seconds / SECSPERDAY);
|
tdays = (time_t)(seconds / SECSPERDAY);
|
||||||
rem += (int_fast64_t)(seconds - tdays * SECSPERDAY);
|
rem += (int_fast64_t)(seconds - tdays * SECSPERDAY);
|
||||||
}
|
}
|
||||||
@ -2179,8 +2184,9 @@ tmcomp(const struct tm *const atmp, const struct tm *const btmp)
|
|||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
if ((result = (atmp->tm_year - btmp->tm_year)) == 0 &&
|
if (atmp->tm_year != btmp->tm_year)
|
||||||
(result = (atmp->tm_mon - btmp->tm_mon)) == 0 &&
|
return atmp->tm_year < btmp->tm_year ? -1 : 1;
|
||||||
|
if ((result = (atmp->tm_mon - btmp->tm_mon)) == 0 &&
|
||||||
(result = (atmp->tm_mday - btmp->tm_mday)) == 0 &&
|
(result = (atmp->tm_mday - btmp->tm_mday)) == 0 &&
|
||||||
(result = (atmp->tm_hour - btmp->tm_hour)) == 0 &&
|
(result = (atmp->tm_hour - btmp->tm_hour)) == 0 &&
|
||||||
(result = (atmp->tm_min - btmp->tm_min)) == 0)
|
(result = (atmp->tm_min - btmp->tm_min)) == 0)
|
||||||
@ -2283,7 +2289,6 @@ again:
|
|||||||
if (!TYPE_SIGNED(time_t)) {
|
if (!TYPE_SIGNED(time_t)) {
|
||||||
lo = 0;
|
lo = 0;
|
||||||
hi = lo - 1;
|
hi = lo - 1;
|
||||||
/* LINTED const not */
|
|
||||||
} else {
|
} else {
|
||||||
lo = 1;
|
lo = 1;
|
||||||
for (i = 0; i < (int) TYPE_BIT(time_t) - 1; ++i)
|
for (i = 0; i < (int) TYPE_BIT(time_t) - 1; ++i)
|
||||||
@ -2309,14 +2314,14 @@ again:
|
|||||||
} else dir = tmcomp(&mytm, &yourtm);
|
} else dir = tmcomp(&mytm, &yourtm);
|
||||||
if (dir != 0) {
|
if (dir != 0) {
|
||||||
if (t == lo) {
|
if (t == lo) {
|
||||||
++t;
|
if (t == time_t_max)
|
||||||
if (t <= lo)
|
|
||||||
goto overflow;
|
goto overflow;
|
||||||
|
++t;
|
||||||
++lo;
|
++lo;
|
||||||
} else if (t == hi) {
|
} else if (t == hi) {
|
||||||
--t;
|
if (t == time_t_min)
|
||||||
if (t >= hi)
|
|
||||||
goto overflow;
|
goto overflow;
|
||||||
|
--t;
|
||||||
--hi;
|
--hi;
|
||||||
}
|
}
|
||||||
#ifdef NO_ERROR_IN_DST_GAP
|
#ifdef NO_ERROR_IN_DST_GAP
|
||||||
@ -2541,8 +2546,7 @@ timeoff(struct tm *const tmp, long offset)
|
|||||||
** previous versions of the CMUCS runtime library.
|
** previous versions of the CMUCS runtime library.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
extern "C"
|
extern "C" long
|
||||||
int_fast32_t
|
|
||||||
gtime(struct tm *const tmp)
|
gtime(struct tm *const tmp)
|
||||||
{
|
{
|
||||||
const time_t t = mktime(tmp);
|
const time_t t = mktime(tmp);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user