28 #define COMPILING_RCPP
73 static const int days_in_month[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
74 static const int year_base = 1900;
76 #define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0)
77 #define days_in_year(year) (isleap(year) ? 366 : 365)
84 year0 = year_base +
tm.tm_year;
87 excess = (int)(year0/2000) - 1;
88 year0 -= excess * 2000;
89 }
else if (year0 < 0) {
90 excess = -1 - (int)(-year0/2000);
91 year0 -= excess * 2000;
94 for(i = 0; i <
tm.tm_mon; i++) day += days_in_month[i];
95 if (
tm.tm_mon > 1 &&
isleap(year0)) day++;
99 for (year = 1970; year < year0; year++)
101 }
else if (year0 < 1970) {
102 for (year = 1969; year >= year0; year--)
107 if ((
tm.tm_wday = (day + 4) % 7) < 0)
tm.tm_wday += 7;
109 return tm.tm_sec + (
tm.tm_min * 60) + (
tm.tm_hour * 3600)
110 + (day + excess * 730485) * 86400.0;
116 #include "sys/types.h"
126 # define EOVERFLOW 79
139 #define TYPE_BIT(type) (sizeof (type) * CHAR_BIT)
140 #define TYPE_SIGNED(type) (((type) -1) < 0)
141 #define TYPE_INTEGRAL(type) (((type) 0.5) != 0.5)
142 #define TWOS_COMPLEMENT(t) ((t) ~ (t) 0 < 0)
143 #define GRANDPARENTED "Local time zone must be set--see zic manual page"
144 #define YEARSPERREPEAT 400
145 #define AVGSECSPERYEAR 31556952L
146 #define SECSPERREPEAT ((int_fast64_t) YEARSPERREPEAT * (int_fast64_t) AVGSECSPERYEAR)
147 #define SECSPERREPEAT_BITS 34
148 #define is_digit(c) ((unsigned)(c) - '0' <= 9)
149 #define INITIALIZE(x) (x = 0)
154 #define MAXVAL(t, b) \
155 ((t) (((t) 1 << ((b) - 1 - TYPE_SIGNED(t))) \
156 - 1 + ((t) 1 << ((b) - 1 - TYPE_SIGNED(t)))))
157 #define MINVAL(t, b) \
158 ((t) (TYPE_SIGNED(t) ? - TWOS_COMPLEMENT(t) - MAXVAL(t, b) : 0))
188 #define TZDIR "/usr/local/etc/zoneinfo"
192 #define TZDEFAULT "localtime"
196 #define TZDEFRULES "America/New_York"
203 #define TZ_MAGIC "TZif"
265 #define TZ_MAX_TIMES 1200
270 #define TZ_MAX_TYPES 256
277 #define TZ_MAX_TYPES 20
283 #define TZ_MAX_CHARS 100
288 #define TZ_MAX_LEAPS 50
291 #define SECSPERMIN 60
292 #define MINSPERHOUR 60
293 #define HOURSPERDAY 24
294 #define DAYSPERWEEK 7
295 #define DAYSPERNYEAR 365
296 #define DAYSPERLYEAR 366
297 #define SECSPERHOUR (SECSPERMIN * MINSPERHOUR)
298 #define SECSPERDAY ((int_fast32_t) SECSPERHOUR * HOURSPERDAY)
299 #define MONSPERYEAR 12
304 #define TM_WEDNESDAY 3
305 #define TM_THURSDAY 4
307 #define TM_SATURDAY 6
310 #define TM_FEBRUARY 1
317 #define TM_SEPTEMBER 8
319 #define TM_NOVEMBER 10
320 #define TM_DECEMBER 11
322 #define TM_YEAR_BASE 1900
324 #define EPOCH_YEAR 1970
325 #define EPOCH_WDAY TM_THURSDAY
327 #define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
341 #define isleap_sum(a, b) isleap((a) % 400 + (b) % 400)
352 #define OPEN_MODE (O_RDONLY | O_BINARY)
355 #define OPEN_MODE O_RDONLY
358 static const char gmt[] =
"GMT";
367 #ifndef TZDEFRULESTRING
368 #define TZDEFRULESTRING ",M4.1.0,M10.5.0"
371 #define BIGGEST(a, b) (((a) > (b)) ? (a) : (b))
374 #define MY_TZNAME_MAX TZNAME_MAX
377 #define MY_TZNAME_MAX 255
417 #define DAY_OF_YEAR 1
418 #define MONTH_NTH_DAY_OF_WEEK 2
421 { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
422 { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
434 #define gmtptr (&gmtmem)
440 static int tzparse(
const char * name,
struct state * sp,
int lastditch);
441 static int typesequiv(
const struct state * sp,
int a,
int b);
442 static const char *
getsecs(
const char * strp, int_fast32_t * secsp);
443 static const char *
getnum(
const char * strp,
int *
const nump,
const int min,
const int max);
444 static const char *
getrule(
const char * strp,
struct rule *
const rulep);
445 static int_fast32_t
transtime(
int year,
const struct rule * rulep, int_fast32_t offset);
446 static struct tm *
timesub(
const time_t *timep, int_fast32_t offset,
const struct state *sp,
struct tm *tmp);
462 if ((i >= 0) ? (j > INT_MAX - i) : (j < INT_MIN - i))
482 static int_fast32_t
detzcode(
const char *
const codep) {
483 int_fast32_t
result = (codep[0] & 0x80) ? -1 : 0;
484 for (
int i = 0; i < 4; ++i)
490 int_fast64_t
result = (codep[0] & 0x80) ? -1 : 0;
491 for (
int i = 0; i < 8; ++i)
507 while ((c = *strp) !=
'\0' && !
is_digit(c) && c !=
',' && c !=
'-' &&
513 static const char *
getqzname(
const char *strp,
const int delim) {
516 while ((c = *strp) !=
'\0' && c != delim)
521 static const char *
getoffset(
const char *strp, int_fast32_t *
const offsetp) {
527 }
else if (*strp ==
'+')
533 *offsetp = -*offsetp;
537 static const char *
getsecs(
const char *strp, int_fast32_t *
const secsp) {
568 static const char *
getnum(
const char * strp,
int *
const nump,
const int min,
const int max) {
572 if (strp == NULL || !
is_digit(c = *strp))
576 num = num * 10 + (c -
'0');
587 static const char *
getrule(
const char * strp,
struct rule *
const rulep) {
595 }
else if (*strp ==
'M') {
632 static int tzload(
const char * name,
struct state *
const sp,
const int doextend) {
640 char buf[2 *
sizeof(
struct tzhead) +
662 char fullname[FILENAME_MAX + 1];
667 doaccess = name[0] ==
'/';
672 snprintf(buf, 1000,
"%s/share/zoneinfo",
678 if ((strlen(p) + strlen(name) + 1) >=
sizeof fullname)
680 (void) strcpy(fullname, p);
681 (void) strcat(fullname,
"/");
682 (void) strcat(fullname, name);
686 if (strchr(name,
'.') != NULL) doaccess = TRUE;
696 if ((fid = open(name,
OPEN_MODE)) == -1) {
704 nread = read(fid, u.buf,
sizeof u.buf);
705 if (close(fid) < 0 || nread <= 0)
707 for (stored = 4; stored <= 8; stored *= 2) {
711 ttisstdcnt = (int)
detzcode(u.tzhead.tzh_ttisstdcnt);
712 ttisgmtcnt = (int)
detzcode(u.tzhead.tzh_ttisgmtcnt);
717 p = u.tzhead.tzh_charcnt +
sizeof u.tzhead.tzh_charcnt;
722 (ttisstdcnt != sp->
typecnt && ttisstdcnt != 0) ||
723 (ttisgmtcnt != sp->
typecnt && ttisgmtcnt != 0))
725 if (nread - (p - u.buf) <
734 for (i = 0; i < sp->
timecnt; ++i) {
738 for (i = 0; i < sp->
timecnt; ++i) {
739 sp->
types[i] = (
unsigned char) *p++;
743 for (i = 0; i < sp->
typecnt; ++i) {
746 ttisp = &sp->
ttis[i];
749 ttisp->
tt_isdst = (
unsigned char) *p++;
757 for (i = 0; i < sp->
charcnt; ++i)
760 for (i = 0; i < sp->
leapcnt; ++i) {
763 lsisp = &sp->
lsis[i];
769 for (i = 0; i < sp->
typecnt; ++i) {
772 ttisp = &sp->
ttis[i];
781 for (i = 0; i < sp->
typecnt; ++i) {
784 ttisp = &sp->
ttis[i];
798 for (i = 0; i < sp->
timecnt - 2; ++i)
799 if (sp->
ats[i] > sp->
ats[i + 1]) {
812 for (j = 0; j + i < sp->
timecnt; ++j) {
813 sp->
ats[j] = sp->
ats[j + i];
823 if (u.tzhead.tzh_version[0] ==
'\0')
826 for (i = 0; i < nread; ++i)
834 if (doextend && nread > 2 &&
835 u.buf[0] ==
'\n' && u.buf[nread - 1] ==
'\n' &&
840 u.buf[nread - 1] =
'\0';
844 for (i = 0; i < 2; ++i)
846 for (i = 0; i < ts.
charcnt; ++i)
879 static int_fast32_t
transtime(
const int year,
const struct rule *
const rulep,
const int_fast32_t offset) {
882 int d, m1, yy0, yy1, yy2, dow;
897 if (leapyear && rulep->
r_day >= 60)
919 m1 = (rulep->
r_mon + 9) % 12 + 1;
920 yy0 = (rulep->
r_mon <= 2) ? (year - 1) : year;
923 dow = ((26 * m1 - 2) / 10 +
924 1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7;
933 d = rulep->
r_day - dow;
936 for (
int i = 1; i < rulep->
r_week; ++i) {
947 for (
int i = 0; i < rulep->
r_mon - 1; ++i)
958 return value + rulep->
r_time + offset;
966 static int tzparse(
const char * name,
struct state *
const sp,
const int lastditch) {
967 const char * stdname;
968 const char * dstname;
971 int_fast32_t stdoffset;
972 int_fast32_t dstoffset;
975 static struct ttinfo zttinfo;
980 stdlen = strlen(name);
982 if (stdlen >=
sizeof sp->
chars)
983 stdlen = (
sizeof sp->
chars) - 1;
992 stdlen = name - stdname;
996 stdlen = name - stdname;
1005 if (load_result != 0)
1007 if (*name !=
'\0') {
1013 dstlen = name - dstname;
1018 dstlen = name - dstname;
1020 if (*name !=
'\0' && *name !=
',' && *name !=
';') {
1025 if (*name ==
'\0' && load_result != 0)
1027 if (*name ==
',' || *name ==
';') {
1036 if ((name =
getrule(name, &start)) == NULL)
1040 if ((name =
getrule(name, &end)) == NULL)
1048 sp->
ttis[0] = sp->
ttis[1] = zttinfo;
1058 for (year =
EPOCH_YEAR; year < yearlim; year++) {
1060 starttime =
transtime(year, &start, stdoffset),
1061 endtime =
transtime(year, &end, dstoffset);
1065 int reversed = endtime < starttime;
1067 int_fast32_t swap = starttime;
1068 starttime = endtime;
1072 || (starttime < endtime
1073 && (endtime - starttime
1075 + (stdoffset - dstoffset))))) {
1079 sp->
ats[timecnt] = janfirst;
1081 (&sp->
ats[timecnt], starttime))
1083 sp->
types[timecnt++] = (
unsigned char) reversed;
1084 sp->
ats[timecnt] = janfirst;
1086 (&sp->
ats[timecnt], endtime))
1088 sp->
types[timecnt++] = !reversed;
1097 int_fast32_t theirstdoffset, theirdstoffset, theiroffset;
1106 for (
int i = 0; i < sp->
timecnt; ++i) {
1107 int j = sp->
types[i];
1115 for (
int i = 0; i < sp->
timecnt; ++i) {
1116 int j = sp->
types[i];
1127 theiroffset = theirstdoffset;
1132 for (
int i = 0; i < sp->
timecnt; ++i) {
1133 int j = sp->
types[i];
1153 sp->
ats[i] += dstoffset -
1156 sp->
ats[i] += stdoffset -
1162 theirdstoffset = theiroffset;
1163 else theirstdoffset = theiroffset;
1168 sp->
ttis[0] = sp->
ttis[1] = zttinfo;
1181 sp->
ttis[0] = zttinfo;
1186 sp->
charcnt = (int)(stdlen + 1);
1192 (void) strncpy(cp, stdname, stdlen);
1196 (void) strncpy(cp, dstname, dstlen);
1197 *(cp + dstlen) =
'\0';
1223 return (y >= 0) ? (y / 4 - y / 100 + y / 400) :
1227 static struct tm *
timesub(
const time_t *
const timep,
const int_fast32_t offset,
1228 const struct state *
const sp,
struct tm *
const tmp) {
1229 const struct lsinfo * lp;
1246 hit = ((i == 0 && lp->
ls_corr > 0) ||
1272 if (! ((!
TYPE_SIGNED(time_t) || INT_MIN <= tdelta)
1273 && tdelta <= INT_MAX))
1275 idelta = (int)tdelta;
1277 idelta = (tdays < 0) ? -1 : 1;
1288 int_fast32_t seconds;
1290 seconds = (int_fast32_t)(tdays *
SECSPERDAY);
1298 rem += offset - corr;
1323 tmp->tm_yday = idays;
1334 if (tmp->tm_wday < 0)
1343 tmp->tm_sec = (int) (rem %
SECSPERMIN) + hit;
1345 for (tmp->tm_mon = 0; idays >= ip[tmp->tm_mon]; ++(tmp->tm_mon))
1346 idays -= ip[tmp->tm_mon];
1347 tmp->tm_mday = (int) (idays + 1);
1349 #if ! (defined(__MINGW32__) || defined(__MINGW64__) || defined(__sun) || defined(sun) || defined(_AIX))
1351 tmp->tm_gmtoff = offset;
1365 static struct tm *
gmtsub(
const time_t *
const timep,
const int_fast32_t offset,
struct tm *
const tmp) {
1377 struct tm *
gmtime_(
const time_t *
const timep) {
#define TYPE_INTEGRAL(type)
#define days_in_year(year)
#define MONTH_NTH_DAY_OF_WEEK
#define SECSPERREPEAT_BITS
#define TYPE_SIGNED(type)
static const char * getoffset(const char *strp, int_fast32_t *const offsetp)
static const char * getnum(const char *strp, int *const nump, const int min, const int max)
static int_fast64_t detzcode64(const char *const codep)
static const char * getrule(const char *strp, struct rule *const rulep)
static const char * getsecs(const char *strp, int_fast32_t *secsp)
static struct tm * gmtsub(const time_t *const timep, const int_fast32_t offset, struct tm *const tmp)
static int differ_by_repeat(const time_t t1, const time_t t0)
static int tzparse(const char *name, struct state *sp, int lastditch)
static int increment_overflow(int *const ip, int j)
static const char * getzname(const char *strp)
static void gmtload(struct state *const sp)
static int typesequiv(const struct state *sp, int a, int b)
static time_t const time_t_max
static const int mon_lengths[2][MONSPERYEAR]
attribute_hidden struct tm * gmtime_(const time_t *const x)
sugar::Max< RTYPE, NA, T > max(const VectorBase< RTYPE, NA, T > &x)
static const char * getqzname(const char *strp, const int delim)
static int leaps_thru_end_of(const int y)
attribute_hidden double mktime00(struct tm &tm)
static time_t const time_t_min
static struct tm * timesub(const time_t *timep, int_fast32_t offset, const struct state *sp, struct tm *tmp)
static int increment_overflow_time(time_t *tp, int_fast32_t j)
static int_fast32_t detzcode(const char *const codep)
static struct state gmtmem
static int_fast32_t transtime(int year, const struct rule *rulep, int_fast32_t offset)
static const int year_lengths[2]
static int tzload(const char *name, struct state *const sp, const int doextend)
sugar::Min< RTYPE, NA, T > min(const VectorBase< RTYPE, NA, T > &x)
struct lsinfo lsis[TZ_MAX_LEAPS]
char chars[BIGGEST(BIGGEST(TZ_MAX_CHARS+1, sizeof gmt),(2 *(MY_TZNAME_MAX+1)))]
unsigned char types[TZ_MAX_TIMES]
struct ttinfo ttis[TZ_MAX_TYPES]