28#include <R_ext/Boolean.h>
72 static const int days_in_month[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
73 static const int year_base = 1900;
75 #define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0)
76 #define days_in_year(year) (isleap(year) ? 366 : 365)
83 year0 = year_base +
tm.tm_year;
86 excess = (int)(year0/2000) - 1;
87 year0 -= (int)(excess * 2000);
88 }
else if (year0 < 0) {
89 excess = -1 - (int)(-year0/2000);
90 year0 -= (int)(excess * 2000);
93 for(i = 0; i <
tm.tm_mon; i++) day += days_in_month[i];
94 if (
tm.tm_mon > 1 &&
isleap(year0)) day++;
98 for (year = 1970; year < year0; year++)
100 }
else if (year0 < 1970) {
101 for (year = 1969; year >= year0; year--)
106 if ((
tm.tm_wday = (day + 4) % 7) < 0)
tm.tm_wday += 7;
108 return tm.tm_sec + (
tm.tm_min * 60) + (
tm.tm_hour * 3600)
109 + (day + excess * 730485) * 86400.0;
115#include "sys/types.h"
138#define TYPE_BIT(type) (sizeof (type) * CHAR_BIT)
139#define TYPE_SIGNED(type) (((type) -1) < 0)
140#define TYPE_INTEGRAL(type) (((type) 0.5) != 0.5)
141#define TWOS_COMPLEMENT(t) ((t) ~ (t) 0 < 0)
142#define GRANDPARENTED "Local time zone must be set--see zic manual page"
143#define YEARSPERREPEAT 400
144#define AVGSECSPERYEAR 31556952L
145#define SECSPERREPEAT ((int_fast64_t) YEARSPERREPEAT * (int_fast64_t) AVGSECSPERYEAR)
146#define SECSPERREPEAT_BITS 34
147#define is_digit(c) ((unsigned)(c) - '0' <= 9)
148#define INITIALIZE(x) (x = 0)
153#define MAXVAL(t, b) \
154 ((t) (((t) 1 << ((b) - 1 - TYPE_SIGNED(t))) \
155 - 1 + ((t) 1 << ((b) - 1 - TYPE_SIGNED(t)))))
156#define MINVAL(t, b) \
157 ((t) (TYPE_SIGNED(t) ? - TWOS_COMPLEMENT(t) - MAXVAL(t, b) : 0))
187#define TZDIR "/usr/local/etc/zoneinfo"
191#define TZDEFAULT "localtime"
195#define TZDEFRULES "America/New_York"
202#define TZ_MAGIC "TZif"
264#define TZ_MAX_TIMES 1200
269#define TZ_MAX_TYPES 256
276#define TZ_MAX_TYPES 20
282#define TZ_MAX_CHARS 100
287#define TZ_MAX_LEAPS 50
291#define MINSPERHOUR 60
292#define HOURSPERDAY 24
294#define DAYSPERNYEAR 365
295#define DAYSPERLYEAR 366
296#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR)
297#define SECSPERDAY ((int_fast32_t) SECSPERHOUR * HOURSPERDAY)
298#define MONSPERYEAR 12
303#define TM_WEDNESDAY 3
316#define TM_SEPTEMBER 8
318#define TM_NOVEMBER 10
319#define TM_DECEMBER 11
321#define TM_YEAR_BASE 1900
323#define EPOCH_YEAR 1970
324#define EPOCH_WDAY TM_THURSDAY
326#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
340#define isleap_sum(a, b) isleap((a) % 400 + (b) % 400)
351#define OPEN_MODE (O_RDONLY | O_BINARY)
354#define OPEN_MODE O_RDONLY
357 static const char gmt[] =
"GMT";
366#ifndef TZDEFRULESTRING
367#define TZDEFRULESTRING ",M4.1.0,M10.5.0"
370#define BIGGEST(a, b) (((a) > (b)) ? (a) : (b))
373#define MY_TZNAME_MAX TZNAME_MAX
376#define MY_TZNAME_MAX 255
417#define MONTH_NTH_DAY_OF_WEEK 2
420 { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
421 { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
433#define gmtptr (&gmtmem)
439 static int tzparse(
const char * name,
struct state * sp,
int lastditch);
441 static const char *
getsecs(
const char * strp, int_fast32_t * secsp);
442 static const char *
getnum(
const char * strp,
int *
const nump,
const int min,
const int max);
443 static const char *
getrule(
const char * strp,
struct rule *
const rulep);
444 static int_fast32_t
transtime(
int year,
const struct rule * rulep, int_fast32_t offset);
445 static struct tm *
timesub(
const time_t *timep, int_fast32_t offset,
const struct state *sp,
struct tm *tmp);
461 if ((i >= 0) ? (j > INT_MAX - i) : (j < INT_MIN - i))
481 static int_fast32_t
detzcode(
const char *
const codep) {
482 int_fast32_t
result = (codep[0] & 0x80) ? -1 : 0;
483 for (
int i = 0; i < 4; ++i)
489 int_fast64_t
result = (codep[0] & 0x80) ? -1 : 0;
490 for (
int i = 0; i < 8; ++i)
506 while ((c = *strp) !=
'\0' && !
is_digit(c) && c !=
',' && c !=
'-' &&
512 static const char *
getqzname(
const char *strp,
const int delim) {
515 while ((c = *strp) !=
'\0' && c != delim)
520 static const char *
getoffset(
const char *strp, int_fast32_t *
const offsetp) {
526 }
else if (*strp ==
'+')
532 *offsetp = -*offsetp;
536 static const char *
getsecs(
const char *strp, int_fast32_t *
const secsp) {
567 static const char *
getnum(
const char * strp,
int *
const nump,
const int min,
const int max) {
571 if (strp == NULL || !
is_digit(c = *strp))
575 num = num * 10 + (c -
'0');
586 static const char *
getrule(
const char * strp,
struct rule *
const rulep) {
594 }
else if (*strp ==
'M') {
631 static int tzload(
const char * name,
struct state *
const sp,
const int doextend) {
639 char buf[2 *
sizeof(
struct tzhead) +
661 char fullname[FILENAME_MAX + 1];
666 doaccess = name[0] ==
'/';
671 snprintf(buf, 1000,
"%s/share/zoneinfo",
677 if ((strlen(p) + strlen(name) + 1) >=
sizeof fullname)
679 (void) strcpy(fullname, p);
680 (void) strcat(fullname,
"/");
681 (void) strcat(fullname, name);
685 if (strchr(name,
'.') != NULL) doaccess = TRUE;
695 if ((fid = open(name,
OPEN_MODE)) == -1) {
703 nread = (int)read(fid, u.buf,
sizeof u.buf);
704 if (close(fid) < 0 || nread <= 0)
706 for (stored = 4; stored <= 8; stored *= 2) {
710 ttisstdcnt = (int)
detzcode(u.tzhead.tzh_ttisstdcnt);
711 ttisgmtcnt = (int)
detzcode(u.tzhead.tzh_ttisgmtcnt);
716 p = u.tzhead.tzh_charcnt +
sizeof u.tzhead.tzh_charcnt;
721 (ttisstdcnt != sp->
typecnt && ttisstdcnt != 0) ||
722 (ttisgmtcnt != sp->
typecnt && ttisgmtcnt != 0))
724 if (nread - (p - u.buf) <
733 for (i = 0; i < sp->
timecnt; ++i) {
737 for (i = 0; i < sp->
timecnt; ++i) {
738 sp->
types[i] = (
unsigned char) *p++;
742 for (i = 0; i < sp->
typecnt; ++i) {
745 ttisp = &sp->
ttis[i];
748 ttisp->
tt_isdst = (
unsigned char) *p++;
756 for (i = 0; i < sp->
charcnt; ++i)
759 for (i = 0; i < sp->
leapcnt; ++i) {
762 lsisp = &sp->
lsis[i];
768 for (i = 0; i < sp->
typecnt; ++i) {
771 ttisp = &sp->
ttis[i];
780 for (i = 0; i < sp->
typecnt; ++i) {
783 ttisp = &sp->
ttis[i];
797 for (i = 0; i < sp->
timecnt - 2; ++i)
798 if (sp->
ats[i] > sp->
ats[i + 1]) {
811 for (j = 0; j + i < sp->
timecnt; ++j) {
812 sp->
ats[j] = sp->
ats[j + i];
822 if (u.tzhead.tzh_version[0] ==
'\0')
825 for (i = 0; i < nread; ++i)
833 if (doextend && nread > 2 &&
834 u.buf[0] ==
'\n' && u.buf[nread - 1] ==
'\n' &&
839 u.buf[nread - 1] =
'\0';
843 for (i = 0; i < 2; ++i)
845 for (i = 0; i < ts.
charcnt; ++i)
878 static int_fast32_t
transtime(
const int year,
const struct rule *
const rulep,
const int_fast32_t offset) {
881 int d, m1, yy0, yy1, yy2, dow;
896 if (leapyear && rulep->
r_day >= 60)
918 m1 = (rulep->
r_mon + 9) % 12 + 1;
919 yy0 = (rulep->
r_mon <= 2) ? (year - 1) : year;
922 dow = ((26 * m1 - 2) / 10 +
923 1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7;
932 d = rulep->
r_day - dow;
935 for (
int i = 1; i < rulep->
r_week; ++i) {
946 for (
int i = 0; i < rulep->
r_mon - 1; ++i)
957 return value + rulep->
r_time + offset;
965 static int tzparse(
const char * name,
struct state *
const sp,
const int lastditch) {
966 const char * stdname;
967 const char * dstname;
970 int_fast32_t stdoffset;
971 int_fast32_t dstoffset;
974 static struct ttinfo zttinfo;
979 stdlen = strlen(name);
981 if (stdlen >=
sizeof sp->
chars)
982 stdlen = (
sizeof sp->
chars) - 1;
991 stdlen = name - stdname;
995 stdlen = name - stdname;
1004 if (load_result != 0)
1006 if (*name !=
'\0') {
1012 dstlen = name - dstname;
1017 dstlen = name - dstname;
1019 if (*name !=
'\0' && *name !=
',' && *name !=
';') {
1024 if (*name ==
'\0' && load_result != 0)
1026 if (*name ==
',' || *name ==
';') {
1035 if ((name =
getrule(name, &start)) == NULL)
1039 if ((name =
getrule(name, &end)) == NULL)
1047 sp->
ttis[0] = sp->
ttis[1] = zttinfo;
1057 for (year =
EPOCH_YEAR; year < yearlim; year++) {
1059 starttime =
transtime(year, &start, stdoffset),
1060 endtime =
transtime(year, &end, dstoffset);
1064 int reversed = endtime < starttime;
1066 int_fast32_t swap = starttime;
1067 starttime = endtime;
1071 || (starttime < endtime
1072 && (endtime - starttime
1074 + (stdoffset - dstoffset))))) {
1078 sp->
ats[timecnt] = janfirst;
1080 (&sp->
ats[timecnt], starttime))
1082 sp->
types[timecnt++] = (
unsigned char) reversed;
1083 sp->
ats[timecnt] = janfirst;
1085 (&sp->
ats[timecnt], endtime))
1087 sp->
types[timecnt++] = !reversed;
1096 int_fast32_t theirstdoffset, theirdstoffset, theiroffset;
1105 for (
int i = 0; i < sp->
timecnt; ++i) {
1106 int j = sp->
types[i];
1114 for (
int i = 0; i < sp->
timecnt; ++i) {
1115 int j = sp->
types[i];
1126 theiroffset = theirstdoffset;
1131 for (
int i = 0; i < sp->
timecnt; ++i) {
1132 int j = sp->
types[i];
1152 sp->
ats[i] += dstoffset -
1155 sp->
ats[i] += stdoffset -
1161 theirdstoffset = theiroffset;
1162 else theirstdoffset = theiroffset;
1167 sp->
ttis[0] = sp->
ttis[1] = zttinfo;
1180 sp->
ttis[0] = zttinfo;
1185 sp->
charcnt = (int)(stdlen + 1);
1191 (void) strncpy(cp, stdname, stdlen);
1195 (void) strncpy(cp, dstname, dstlen);
1196 *(cp + dstlen) =
'\0';
1222 return (y >= 0) ? (y / 4 - y / 100 + y / 400) :
1226 static struct tm *
timesub(
const time_t *
const timep,
const int_fast32_t offset,
1227 const struct state *
const sp,
struct tm *
const tmp) {
1228 const struct lsinfo * lp;
1245 hit = ((i == 0 && lp->
ls_corr > 0) ||
1271 if (! ((!
TYPE_SIGNED(time_t) || INT_MIN <= tdelta)
1272 && tdelta <= INT_MAX))
1274 idelta = (int)tdelta;
1276 idelta = (tdays < 0) ? -1 : 1;
1287 int_fast32_t seconds;
1289 seconds = (int_fast32_t)(tdays *
SECSPERDAY);
1297 rem += offset - corr;
1322 tmp->tm_yday = idays;
1333 if (tmp->tm_wday < 0)
1342 tmp->tm_sec = (int) (rem %
SECSPERMIN) + hit;
1344 for (tmp->tm_mon = 0; idays >= ip[tmp->tm_mon]; ++(tmp->tm_mon))
1345 idays -= ip[tmp->tm_mon];
1346 tmp->tm_mday = (int) (idays + 1);
1348#if ! (defined(__MINGW32__) || defined(__MINGW64__) || defined(__sun) || defined(sun) || defined(_AIX))
1350 tmp->tm_gmtoff = offset;
1364 static struct tm *
gmtsub(
const time_t *
const timep,
const int_fast32_t offset,
struct tm *
const tmp) {
1376 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 * 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)
sugar::Min< RTYPE, NA, T > min(const VectorBase< RTYPE, NA, T > &x)
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 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 char * getqzname(const char *strp, const int delim)
static const int mon_lengths[2][MONSPERYEAR]
static const char * getzname(const char *strp)
static struct tm * gmtsub(const time_t *const timep, const int_fast32_t offset, struct tm *const tmp)
attribute_hidden struct tm * gmtime_(const time_t *const x)
static const char * getoffset(const char *strp, int_fast32_t *const offsetp)
sugar::Max< RTYPE, NA, T > max(const VectorBase< RTYPE, NA, T > &x)
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)
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]