Rcpp Version 1.0.9
date.cpp
Go to the documentation of this file.
1 
2 //
3 // Date.cpp: Rcpp R/C++ interface class library -- Date type
4 //
5 // Copyright (C) 2010 - 2019 Dirk Eddelbuettel and Romain Francois
6 //
7 // The mktime00() as well as the gmtime_() replacement function are
8 // Copyright (C) 2000 - 2010 The R Development Core Team.
9 //
10 // gmtime_() etc are from the public domain timezone code dated
11 // 1996-06-05 by Arthur David Olson.
12 //
13 // This file is part of Rcpp.
14 //
15 // Rcpp is free software: you can redistribute it and/or modify it
16 // under the terms of the GNU General Public License as published by
17 // the Free Software Foundation, either version 2 of the License, or
18 // (at your option) any later version.
19 //
20 // Rcpp is distributed in the hope that it will be useful, but
21 // WITHOUT ANY WARRANTY; without even the implied warranty of
22 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 // GNU General Public License for more details.
24 //
25 // You should have received a copy of the GNU General Public License
26 // along with Rcpp. If not, see <http://www.gnu.org/licenses/>.
27 
28 #define COMPILING_RCPP
29 
30 #include <Rcpp.h>
31 #include <time.h> // for gmtime
32 #include <Rcpp/exceptions.h>
33 
34 namespace Rcpp {
35 
36  // Taken (in 2010) from R's src/main/datetime.c and made a member function called with C++ reference
37  // Later, R added the following comment we now (in 2016) add
38 
39  /*
40 
41  There are two implementation paths here.
42 
43  1) Use the system functions for mktime, gmtime[_r], localtime[_r], strftime.
44  Use the system time_t, struct tm and time-zone tables.
45 
46  2) Use substitutes from src/extra/tzone for mktime, gmtime, localtime,
47  strftime with a R_ prefix. The system strftime is used for
48  locale-dependent names in R_strptime and R_strftime. This uses the
49  time-zone tables shipped with R and installed into
50  R_HOME/share/zoneinfo .
51 
52  Our own versions of time_t (64-bit) and struct tm (including the
53  BSD-style fields tm_zone and tm_gmtoff) are used.
54 
55  For path 1), the system facilities are used for 1902-2037 and outside
56  those limits where there is a 64-bit time_t and the conversions work
57  (most OSes currently have only 32-bit time-zone tables). Otherwise
58  there is code below to extrapolate from 1902-2037.
59 
60  Path 2) was added for R 3.1.0 and is the only one supported on
61  Windows: it is the default on macOS. The only currently (Jan 2014)
62  known OS with 64-bit time_t and complete tables is Linux.
63 
64  */
65 
66  // Now, R only ships share/zoneinfo on Windows AFAIK
67 
68  /* Substitute for mktime -- no checking, always in GMT */
69 
70  // [[Rcpp::register]]
71  double mktime00(struct tm &tm) {
72 
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;
75 
76  #define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0)
77  #define days_in_year(year) (isleap(year) ? 366 : 365)
78 
79  int day = 0;
80  int i, year, year0;
81  double excess = 0.0;
82 
83  day = tm.tm_mday - 1;
84  year0 = year_base + tm.tm_year;
85  /* safety check for unbounded loops */
86  if (year0 > 3000) {
87  excess = (int)(year0/2000) - 1; // #nocov start
88  year0 -= excess * 2000;
89  } else if (year0 < 0) {
90  excess = -1 - (int)(-year0/2000);
91  year0 -= excess * 2000; // #nocov end
92  }
93 
94  for(i = 0; i < tm.tm_mon; i++) day += days_in_month[i];
95  if (tm.tm_mon > 1 && isleap(year0)) day++;
96  tm.tm_yday = day;
97 
98  if (year0 > 1970) {
99  for (year = 1970; year < year0; year++)
100  day += days_in_year(year);
101  } else if (year0 < 1970) {
102  for (year = 1969; year >= year0; year--)
103  day -= days_in_year(year);
104  }
105 
106  /* weekday: Epoch day was a Thursday */
107  if ((tm.tm_wday = (day + 4) % 7) < 0) tm.tm_wday += 7;
108 
109  return tm.tm_sec + (tm.tm_min * 60) + (tm.tm_hour * 3600)
110  + (day + excess * 730485) * 86400.0;
111  }
112 
113  #undef isleap
114  #undef days_in_year
115 
116 #include "sys/types.h" /* for time_t */
117 #include "string.h"
118 #include "limits.h" /* for CHAR_BIT et al. */
119 
120 #define _NO_OLDNAMES /* avoid tznames */
121 #include "time.h"
122 #undef _NO_OLDNAMES
123 
124 #include <errno.h>
125 #ifndef EOVERFLOW
126 # define EOVERFLOW 79
127 #endif
128 
129 #include "stdlib.h"
130 #include "stdint.h"
131 #include "stdio.h"
132 #include "fcntl.h"
133 #include "float.h" /* for FLT_MAX and DBL_MAX */
134 
135 #include <unistd.h> // solaris needs this for read() and close()
136 
137 
138 /* merged from private.h */
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 /* years before a Gregorian repeat */
145 #define AVGSECSPERYEAR 31556952L
146 #define SECSPERREPEAT ((int_fast64_t) YEARSPERREPEAT * (int_fast64_t) AVGSECSPERYEAR)
147 #define SECSPERREPEAT_BITS 34 /* ceil(log2(SECSPERREPEAT)) */
148 #define is_digit(c) ((unsigned)(c) - '0' <= 9)
149 #define INITIALIZE(x) (x = 0)
150 
151 /* Max and min values of the integer type T, of which only the bottom
152  B bits are used, and where the highest-order used bit is considered
153  to be a sign bit if T is signed. */
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))
159 
160 /* The minimum and maximum finite time values. This assumes no padding. */
161 static time_t const time_t_min = MINVAL(time_t, TYPE_BIT(time_t));
162 static time_t const time_t_max = MAXVAL(time_t, TYPE_BIT(time_t));
163 
164  //#include "tzfile.h" // from src/extra/tzone/tzfile.h
165  // BEGIN ------------------------------------------------------------------------------------------ tzfile.h
166 #ifndef TZFILE_H
167 
168 #define TZFILE_H
169 
170 /*
171 ** This file is in the public domain, so clarified as of
172 ** 1996-06-05 by Arthur David Olson.
173 */
174 
175 /*
176 ** This header is for use ONLY with the time conversion code.
177 ** There is no guarantee that it will remain unchanged,
178 ** or that it will remain at all.
179 ** Do NOT copy it to any system include directory.
180 ** Thank you!
181 */
182 
183 /*
184 ** Information about time zone files.
185 */
186 
187 #ifndef TZDIR
188 #define TZDIR "/usr/local/etc/zoneinfo" /* Time zone object file directory */
189 #endif /* !defined TZDIR */
190 
191 #ifndef TZDEFAULT
192 #define TZDEFAULT "localtime" // NB this is "UTC" in R, but R also loads tz data
193 #endif /* !defined TZDEFAULT */
194 
195 #ifndef TZDEFRULES
196 #define TZDEFRULES "America/New_York"
197 #endif /* !defined TZDEFRULES */
198 
199 /*
200 ** Each file begins with. . .
201 */
202 
203 #define TZ_MAGIC "TZif"
204 
205 struct tzhead {
206  char tzh_magic[4]; /* TZ_MAGIC */
207  char tzh_version[1]; /* '\0' or '2' as of 2005 */
208  char tzh_reserved[15]; /* reserved--must be zero */
209  char tzh_ttisgmtcnt[4]; /* coded number of trans. time flags */
210  char tzh_ttisstdcnt[4]; /* coded number of trans. time flags */
211  char tzh_leapcnt[4]; /* coded number of leap seconds */
212  char tzh_timecnt[4]; /* coded number of transition times */
213  char tzh_typecnt[4]; /* coded number of local time types */
214  char tzh_charcnt[4]; /* coded number of abbr. chars */
215 };
216 
217 /*
218 ** . . .followed by. . .
219 **
220 ** tzh_timecnt (char [4])s coded transition times a la time(2)
221 ** tzh_timecnt (unsigned char)s types of local time starting at above
222 ** tzh_typecnt repetitions of
223 ** one (char [4]) coded UTC offset in seconds
224 ** one (unsigned char) used to set tm_isdst
225 ** one (unsigned char) that's an abbreviation list index
226 ** tzh_charcnt (char)s '\0'-terminated zone abbreviations
227 ** tzh_leapcnt repetitions of
228 ** one (char [4]) coded leap second transition times
229 ** one (char [4]) total correction after above
230 ** tzh_ttisstdcnt (char)s indexed by type; if TRUE, transition
231 ** time is standard time, if FALSE,
232 ** transition time is wall clock time
233 ** if absent, transition times are
234 ** assumed to be wall clock time
235 ** tzh_ttisgmtcnt (char)s indexed by type; if TRUE, transition
236 ** time is UTC, if FALSE,
237 ** transition time is local time
238 ** if absent, transition times are
239 ** assumed to be local time
240 */
241 
242 /*
243 ** If tzh_version is '2' or greater, the above is followed by a second instance
244 ** of tzhead and a second instance of the data in which each coded transition
245 ** time uses 8 rather than 4 chars,
246 ** then a POSIX-TZ-environment-variable-style string for use in handling
247 ** instants after the last transition time stored in the file
248 ** (with nothing between the newlines if there is no POSIX representation for
249 ** such instants).
250 **
251 ** If tz_version is '3' or greater, the above is extended as follows.
252 ** First, the POSIX TZ string's hour offset may range from -167
253 ** through 167 as compared to the POSIX-required 0 through 24.
254 ** Second, its DST start time may be January 1 at 00:00 and its stop
255 ** time December 31 at 24:00 plus the difference between DST and
256 ** standard time, indicating DST all year.
257 */
258 
259 /*
260 ** In the current implementation, "tzset()" refuses to deal with files that
261 ** exceed any of the limits below.
262 */
263 
264 #ifndef TZ_MAX_TIMES
265 #define TZ_MAX_TIMES 1200
266 #endif /* !defined TZ_MAX_TIMES */
267 
268 #ifndef TZ_MAX_TYPES
269 #ifndef NOSOLAR
270 #define TZ_MAX_TYPES 256 /* Limited by what (unsigned char)'s can hold */
271 #endif /* !defined NOSOLAR */
272 #ifdef NOSOLAR
273 /*
274 ** Must be at least 14 for Europe/Riga as of Jan 12 1995,
275 ** as noted by Earl Chew.
276 */
277 #define TZ_MAX_TYPES 20 /* Maximum number of local time types */
278 #endif /* !defined NOSOLAR */
279 #endif /* !defined TZ_MAX_TYPES */
280 
281 // increased from 50, http://mm.icann.org/pipermail/tz/2015-August/022623.html
282 #ifndef TZ_MAX_CHARS
283 #define TZ_MAX_CHARS 100 /* Maximum number of abbreviation characters */
284  /* (limited by what unsigned chars can hold) */
285 #endif /* !defined TZ_MAX_CHARS */
286 
287 #ifndef TZ_MAX_LEAPS
288 #define TZ_MAX_LEAPS 50 /* Maximum number of leap second corrections */
289 #endif /* !defined TZ_MAX_LEAPS */
290 
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
300 
301 #define TM_SUNDAY 0
302 #define TM_MONDAY 1
303 #define TM_TUESDAY 2
304 #define TM_WEDNESDAY 3
305 #define TM_THURSDAY 4
306 #define TM_FRIDAY 5
307 #define TM_SATURDAY 6
308 
309 #define TM_JANUARY 0
310 #define TM_FEBRUARY 1
311 #define TM_MARCH 2
312 #define TM_APRIL 3
313 #define TM_MAY 4
314 #define TM_JUNE 5
315 #define TM_JULY 6
316 #define TM_AUGUST 7
317 #define TM_SEPTEMBER 8
318 #define TM_OCTOBER 9
319 #define TM_NOVEMBER 10
320 #define TM_DECEMBER 11
321 
322 #define TM_YEAR_BASE 1900
323 
324 #define EPOCH_YEAR 1970
325 #define EPOCH_WDAY TM_THURSDAY
326 
327 #define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
328 
329 /*
330 ** Since everything in isleap is modulo 400 (or a factor of 400), we know that
331 ** isleap(y) == isleap(y % 400)
332 ** and so
333 ** isleap(a + b) == isleap((a + b) % 400)
334 ** or
335 ** isleap(a + b) == isleap(a % 400 + b % 400)
336 ** This is true even if % means modulo rather than Fortran remainder
337 ** (which is allowed by C89 but not C99).
338 ** We use this to avoid addition overflow problems.
339 */
340 
341 #define isleap_sum(a, b) isleap((a) % 400 + (b) % 400)
342 
343 #endif /* !defined TZFILE_H */
344 
345  // -------------------------------------------------------------------------------------- END tzfile.h
346 
347  //#include "localtime.c" // from src/extra/tzone/localtime.c
348  // note though that was included is partial as we support only gmtime_()
349  // BEGIN --------------------------------------------------------------------------------- localtime.c
350 
351 #ifdef O_BINARY
352 #define OPEN_MODE (O_RDONLY | O_BINARY)
353 #endif /* defined O_BINARY */
354 #ifndef O_BINARY
355 #define OPEN_MODE O_RDONLY
356 #endif /* !defined O_BINARY */
357 
358  static const char gmt[] = "GMT";
359 
360  /*
361  ** The DST rules to use if TZ has no rules and we can't load TZDEFRULES.
362  ** We default to US rules as of 1999-08-17.
363  ** POSIX 1003.1 section 8.1.1 says that the default DST rules are
364  ** implementation dependent; for historical reasons, US rules are a
365  ** common default.
366  */
367 #ifndef TZDEFRULESTRING
368 #define TZDEFRULESTRING ",M4.1.0,M10.5.0"
369 #endif /* !defined TZDEFDST */
370 
371 #define BIGGEST(a, b) (((a) > (b)) ? (a) : (b))
372 
373 #ifdef TZNAME_MAX
374 #define MY_TZNAME_MAX TZNAME_MAX
375 #endif /* defined TZNAME_MAX */
376 #ifndef TZNAME_MAX
377 #define MY_TZNAME_MAX 255
378 #endif /* !defined TZNAME_MAX */
379 
380  struct ttinfo { /* time type information */
381  int_fast32_t tt_gmtoff; /* UTC offset in seconds */
382  int tt_isdst; /* used to set tm_isdst */
383  int tt_abbrind; /* abbreviation list index */
384  int tt_ttisstd; /* TRUE if transition is std time */
385  int tt_ttisgmt; /* TRUE if transition is UTC */
386  };
387 
388  struct lsinfo { /* leap second information */
389  time_t ls_trans; /* transition time */
390  int_fast64_t ls_corr; /* correction to apply */
391  };
392 
393  struct state {
394  int leapcnt;
395  int timecnt;
396  int typecnt;
397  int charcnt;
398  int goback;
399  int goahead;
400  time_t ats[TZ_MAX_TIMES];
401  unsigned char types[TZ_MAX_TIMES];
402  struct ttinfo ttis[TZ_MAX_TYPES];
403  char chars[BIGGEST(BIGGEST(TZ_MAX_CHARS + 1, sizeof gmt),
404  (2 * (MY_TZNAME_MAX + 1)))];
405  struct lsinfo lsis[TZ_MAX_LEAPS];
406  };
407 
408  struct rule {
409  int r_type; /* type of rule--see below */
410  int r_day; /* day number of rule */
411  int r_week; /* week number of rule */
412  int r_mon; /* month number of rule */
413  int_fast32_t r_time; /* transition time of rule */
414  };
415 
416 #define JULIAN_DAY 0 /* Jn - Julian day */
417 #define DAY_OF_YEAR 1 /* n - day of year */
418 #define MONTH_NTH_DAY_OF_WEEK 2 /* Mm.n.d - month, week, day of week */
419 
420  static const int mon_lengths[2][MONSPERYEAR] = {
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 }
423  };
424 
425  static const int year_lengths[2] = {
427  };
428 
429  static int gmt_is_set;
430 
431  //static struct state lclmem;
432  static struct state gmtmem;
433  //#define lclptr (&lclmem)
434 #define gmtptr (&gmtmem)
435 
436  static struct tm tm;
437 
438  //extern const char *getTZinfo(void);
439 
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);
447  static int leaps_thru_end_of(const int y);
448 
449  /*
450  ** Normalize logic courtesy Paul Eggert.
451  */
452 
453  static int increment_overflow(int *const ip, int j) {
454  int const i = *ip;
455 
456  /*
457  ** If i >= 0 there can only be overflow if i + j > INT_MAX
458  ** or if j > INT_MAX - i; given i >= 0, INT_MAX - i cannot overflow.
459  ** If i < 0 there can only be overflow if i + j < INT_MIN
460  ** or if j < INT_MIN - i; given i < 0, INT_MIN - i cannot overflow.
461  */
462  if ((i >= 0) ? (j > INT_MAX - i) : (j < INT_MIN - i))
463  return TRUE; // #nocov
464  *ip += j;
465  return FALSE;
466  }
467 
468  static int increment_overflow_time(time_t *tp, int_fast32_t j) { // #nocov start
469  /*
470  ** This is like
471  ** 'if (! (time_t_min <= *tp + j && *tp + j <= time_t_max)) ...',
472  ** except that it does the right thing even if *tp + j would overflow.
473  */
474  if (! (j < 0
475  ? (TYPE_SIGNED(time_t) ? time_t_min - j <= *tp : -1 - j < *tp)
476  : *tp <= time_t_max - j))
477  return TRUE;
478  *tp += j;
479  return FALSE;
480  }
481 
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)
485  result = (result << 8) | (codep[i] & 0xff);
486  return result;
487  }
488 
489  static int_fast64_t detzcode64(const char *const codep) {
490  int_fast64_t result = (codep[0] & 0x80) ? -1 : 0;
491  for (int i = 0; i < 8; ++i)
492  result = (result << 8) | (codep[i] & 0xff);
493  return result;
494  }
495 
496  static int differ_by_repeat(const time_t t1, const time_t t0) {
497  if (TYPE_INTEGRAL(time_t) &&
498  TYPE_BIT(time_t) - TYPE_SIGNED(time_t) < SECSPERREPEAT_BITS)
499  return 0;
500  /* R change */
501  return (int_fast64_t)t1 - (int_fast64_t)t0 == SECSPERREPEAT;
502  }
503 
504  static const char * getzname(const char * strp) {
505  char c;
506 
507  while ((c = *strp) != '\0' && !is_digit(c) && c != ',' && c != '-' &&
508  c != '+')
509  ++strp;
510  return strp;
511  }
512 
513  static const char * getqzname(const char *strp, const int delim) {
514  int c;
515 
516  while ((c = *strp) != '\0' && c != delim)
517  ++strp;
518  return strp;
519  }
520 
521  static const char * getoffset(const char *strp, int_fast32_t *const offsetp) {
522  int neg = 0;
523 
524  if (*strp == '-') {
525  neg = 1;
526  ++strp;
527  } else if (*strp == '+')
528  ++strp;
529  strp = getsecs(strp, offsetp);
530  if (strp == NULL)
531  return NULL; /* illegal time */
532  if (neg)
533  *offsetp = -*offsetp;
534  return strp;
535  }
536 
537  static const char * getsecs(const char *strp, int_fast32_t *const secsp) {
538  int num;
539 
540  /*
541  ** 'HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-Posix rules like
542  ** "M10.4.6/26", which does not conform to Posix,
543  ** but which specifies the equivalent of
544  ** "02:00 on the first Sunday on or after 23 Oct".
545  */
546  strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1);
547  if (strp == NULL)
548  return NULL;
549  *secsp = num * (int_fast32_t) SECSPERHOUR;
550  if (*strp == ':') {
551  ++strp;
552  strp = getnum(strp, &num, 0, MINSPERHOUR - 1);
553  if (strp == NULL)
554  return NULL;
555  *secsp += num * SECSPERMIN;
556  if (*strp == ':') {
557  ++strp;
558  /* 'SECSPERMIN' allows for leap seconds. */
559  strp = getnum(strp, &num, 0, SECSPERMIN);
560  if (strp == NULL)
561  return NULL;
562  *secsp += num;
563  }
564  }
565  return strp;
566  }
567 
568  static const char * getnum(const char * strp, int * const nump, const int min, const int max) {
569  char c;
570  int num;
571 
572  if (strp == NULL || !is_digit(c = *strp))
573  return NULL;
574  num = 0;
575  do {
576  num = num * 10 + (c - '0');
577  if (num > max)
578  return NULL; /* illegal value */
579  c = *++strp;
580  } while (is_digit(c));
581  if (num < min)
582  return NULL; /* illegal value */
583  *nump = num;
584  return strp;
585  }
586 
587  static const char * getrule(const char * strp, struct rule * const rulep) {
588  if (*strp == 'J') {
589  /*
590  ** Julian day.
591  */
592  rulep->r_type = JULIAN_DAY;
593  ++strp;
594  strp = getnum(strp, &rulep->r_day, 1, DAYSPERNYEAR);
595  } else if (*strp == 'M') {
596  /*
597  ** Month, week, day.
598  */
599  rulep->r_type = MONTH_NTH_DAY_OF_WEEK;
600  ++strp;
601  strp = getnum(strp, &rulep->r_mon, 1, MONSPERYEAR);
602  if (strp == NULL)
603  return NULL;
604  if (*strp++ != '.')
605  return NULL;
606  strp = getnum(strp, &rulep->r_week, 1, 5);
607  if (strp == NULL)
608  return NULL;
609  if (*strp++ != '.')
610  return NULL;
611  strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1);
612  } else if (is_digit(*strp)) {
613  /*
614  ** Day of year.
615  */
616  rulep->r_type = DAY_OF_YEAR;
617  strp = getnum(strp, &rulep->r_day, 0, DAYSPERLYEAR - 1);
618  } else return NULL; /* invalid format */
619  if (strp == NULL)
620  return NULL;
621  if (*strp == '/') {
622  /*
623  ** Time specified.
624  */
625  ++strp;
626  strp = getsecs(strp, &rulep->r_time);
627  } else rulep->r_time = 2 * SECSPERHOUR; /* default = 2:00:00 */
628  return strp;
629  }
630 
631  // this routine modified / simplified / reduced in 2010
632  static int tzload(const char * name, struct state * const sp, const int doextend) {
633  const char * p;
634  int i;
635  int fid;
636  int stored;
637  int nread;
638  union {
639  struct tzhead tzhead;
640  char buf[2 * sizeof(struct tzhead) +
641  2 * sizeof *sp + 4 * TZ_MAX_TIMES];
642  } u;
643 
644  sp->goback = sp->goahead = FALSE;
645  /* if (name == NULL && (name = TZDEFAULT) == NULL) return -1; */
646  if (name == NULL) {
647  // edd 06 Jul 2010 let's do without getTZinfo()
648  //name = getTZinfo();
649  //if( strcmp(name, "unknown") == 0 ) name = TZDEFAULT;
650  name = TZDEFAULT;
651  }
652 
653  {
654  int doaccess;
655  /*
656  ** Section 4.9.1 of the C standard says that
657  ** "FILENAME_MAX expands to an integral constant expression
658  ** that is the size needed for an array of char large enough
659  ** to hold the longest file name string that the implementation
660  ** guarantees can be opened."
661  */
662  char fullname[FILENAME_MAX + 1];
663  // edd 08 Jul 2010 not currently needed const char *sname = name;
664 
665  if (name[0] == ':')
666  ++name;
667  doaccess = name[0] == '/';
668  if (!doaccess) {
669  char buf[1000];
670  p = getenv("TZDIR");
671  if (p == NULL) {
672  snprintf(buf, 1000, "%s/share/zoneinfo",
673  getenv("R_HOME"));
674  buf[999] = '\0';
675  p = buf;
676  }
677  /* if ((p = TZDIR) == NULL) return -1; */
678  if ((strlen(p) + strlen(name) + 1) >= sizeof fullname)
679  return -1;
680  (void) strcpy(fullname, p);
681  (void) strcat(fullname, "/");
682  (void) strcat(fullname, name);
683  /*
684  ** Set doaccess if '.' (as in "../") shows up in name.
685  */
686  if (strchr(name, '.') != NULL) doaccess = TRUE;
687  name = fullname;
688  }
689  // edd 16 Jul 2010 comment out whole block
690  //if (doaccess && access(name, R_OK) != 0) {
691  // edd 08 Jul 2010 we use this without TZ for dates only
692  // so no need to warn
693  //Rf_warning("unknown timezone '%s'", sname);
694  //return -1;
695  //}
696  if ((fid = open(name, OPEN_MODE)) == -1) {
697  // edd 08 Jul 2010 we use this without TZ for dates only
698  // so no need to warn
699  //Rf_warning("unknown timezone '%s'", sname);
700  return -1;
701  }
702 
703  }
704  nread = read(fid, u.buf, sizeof u.buf);
705  if (close(fid) < 0 || nread <= 0)
706  return -1;
707  for (stored = 4; stored <= 8; stored *= 2) {
708  int ttisstdcnt;
709  int ttisgmtcnt;
710 
711  ttisstdcnt = (int) detzcode(u.tzhead.tzh_ttisstdcnt);
712  ttisgmtcnt = (int) detzcode(u.tzhead.tzh_ttisgmtcnt);
713  sp->leapcnt = (int) detzcode(u.tzhead.tzh_leapcnt);
714  sp->timecnt = (int) detzcode(u.tzhead.tzh_timecnt);
715  sp->typecnt = (int) detzcode(u.tzhead.tzh_typecnt);
716  sp->charcnt = (int) detzcode(u.tzhead.tzh_charcnt);
717  p = u.tzhead.tzh_charcnt + sizeof u.tzhead.tzh_charcnt;
718  if (sp->leapcnt < 0 || sp->leapcnt > TZ_MAX_LEAPS ||
719  sp->typecnt <= 0 || sp->typecnt > TZ_MAX_TYPES ||
720  sp->timecnt < 0 || sp->timecnt > TZ_MAX_TIMES ||
721  sp->charcnt < 0 || sp->charcnt > TZ_MAX_CHARS ||
722  (ttisstdcnt != sp->typecnt && ttisstdcnt != 0) ||
723  (ttisgmtcnt != sp->typecnt && ttisgmtcnt != 0))
724  return -1;
725  if (nread - (p - u.buf) <
726  sp->timecnt * stored + /* ats */
727  sp->timecnt + /* types */
728  sp->typecnt * 6 + /* ttinfos */
729  sp->charcnt + /* chars */
730  sp->leapcnt * (stored + 4) + /* lsinfos */
731  ttisstdcnt + /* ttisstds */
732  ttisgmtcnt) /* ttisgmts */
733  return -1;
734  for (i = 0; i < sp->timecnt; ++i) {
735  sp->ats[i] = (stored == 4) ? detzcode(p) : detzcode64(p);
736  p += stored;
737  }
738  for (i = 0; i < sp->timecnt; ++i) {
739  sp->types[i] = (unsigned char) *p++;
740  if (sp->types[i] >= sp->typecnt)
741  return -1;
742  }
743  for (i = 0; i < sp->typecnt; ++i) {
744  struct ttinfo * ttisp;
745 
746  ttisp = &sp->ttis[i];
747  ttisp->tt_gmtoff = detzcode(p);
748  p += 4;
749  ttisp->tt_isdst = (unsigned char) *p++;
750  if (ttisp->tt_isdst != 0 && ttisp->tt_isdst != 1)
751  return -1;
752  ttisp->tt_abbrind = (unsigned char) *p++;
753  if (ttisp->tt_abbrind < 0 ||
754  ttisp->tt_abbrind > sp->charcnt)
755  return -1;
756  }
757  for (i = 0; i < sp->charcnt; ++i)
758  sp->chars[i] = *p++;
759  sp->chars[i] = '\0'; /* ensure '\0' at end */
760  for (i = 0; i < sp->leapcnt; ++i) {
761  struct lsinfo * lsisp;
762 
763  lsisp = &sp->lsis[i];
764  lsisp->ls_trans = (stored == 4) ? detzcode(p) : detzcode64(p);
765  p += stored;
766  lsisp->ls_corr = detzcode(p);
767  p += 4;
768  }
769  for (i = 0; i < sp->typecnt; ++i) {
770  struct ttinfo * ttisp;
771 
772  ttisp = &sp->ttis[i];
773  if (ttisstdcnt == 0)
774  ttisp->tt_ttisstd = FALSE;
775  else {
776  ttisp->tt_ttisstd = *p++;
777  if (ttisp->tt_ttisstd != TRUE && ttisp->tt_ttisstd != FALSE)
778  return -1;
779  }
780  }
781  for (i = 0; i < sp->typecnt; ++i) {
782  struct ttinfo * ttisp;
783 
784  ttisp = &sp->ttis[i];
785  if (ttisgmtcnt == 0)
786  ttisp->tt_ttisgmt = FALSE;
787  else {
788  ttisp->tt_ttisgmt = *p++;
789  if (ttisp->tt_ttisgmt != TRUE && ttisp->tt_ttisgmt != FALSE)
790  return -1;
791  }
792  }
793  /*
794  ** Out-of-sort ats should mean we're running on a
795  ** signed time_t system but using a data file with
796  ** unsigned values (or vice versa).
797  */
798  for (i = 0; i < sp->timecnt - 2; ++i)
799  if (sp->ats[i] > sp->ats[i + 1]) {
800  ++i;
801  if (TYPE_SIGNED(time_t)) {
802  /*
803  ** Ignore the end (easy).
804  */
805  sp->timecnt = i;
806  } else {
807  /*
808  ** Ignore the beginning (harder).
809  */
810  int j;
811 
812  for (j = 0; j + i < sp->timecnt; ++j) {
813  sp->ats[j] = sp->ats[j + i];
814  sp->types[j] = sp->types[j + i];
815  }
816  sp->timecnt = j;
817  }
818  break;
819  }
820  /*
821  ** If this is an old file, we're done.
822  */
823  if (u.tzhead.tzh_version[0] == '\0')
824  break;
825  nread -= p - u.buf;
826  for (i = 0; i < nread; ++i)
827  u.buf[i] = p[i];
828  /*
829  ** If this is a narrow integer time_t system, we're done.
830  */
831  if (stored >= (int) sizeof(time_t) && TYPE_INTEGRAL(time_t))
832  break;
833  }
834  if (doextend && nread > 2 &&
835  u.buf[0] == '\n' && u.buf[nread - 1] == '\n' &&
836  sp->typecnt + 2 <= TZ_MAX_TYPES) {
837  struct state ts;
838  int result;
839 
840  u.buf[nread - 1] = '\0';
841  result = tzparse(&u.buf[1], &ts, FALSE);
842  if (result == 0 && ts.typecnt == 2 &&
843  sp->charcnt + ts.charcnt <= TZ_MAX_CHARS) {
844  for (i = 0; i < 2; ++i)
845  ts.ttis[i].tt_abbrind += sp->charcnt;
846  for (i = 0; i < ts.charcnt; ++i)
847  sp->chars[sp->charcnt++] = ts.chars[i];
848  i = 0;
849  while (i < ts.timecnt && ts.ats[i] <= sp->ats[sp->timecnt - 1])
850  ++i;
851  while (i < ts.timecnt &&
852  sp->timecnt < TZ_MAX_TIMES) {
853  sp->ats[sp->timecnt] = ts.ats[i];
854  sp->types[sp->timecnt] = sp->typecnt + ts.types[i];
855  ++sp->timecnt;
856  ++i;
857  }
858  sp->ttis[sp->typecnt++] = ts.ttis[0];
859  sp->ttis[sp->typecnt++] = ts.ttis[1];
860  }
861  }
862  i = 2 * YEARSPERREPEAT;
863  sp->goback = sp->goahead = sp->timecnt > i;
864  sp->goback = sp->goback &&
865  typesequiv(sp, sp->types[i], sp->types[0]) &&
866  differ_by_repeat(sp->ats[i], sp->ats[0]);
867  sp->goahead = sp->goahead &&
868  typesequiv(sp, sp->types[sp->timecnt - 1],
869  sp->types[sp->timecnt - 1 - i]) &&
870  differ_by_repeat(sp->ats[sp->timecnt - 1],
871  sp->ats[sp->timecnt - 1 - i]);
872  return 0;
873  }
874 
875  /*
876  ** Given a year, a rule, and the offset from UT at the time that rule takes
877  ** effect, calculate the year-relative time that rule takes effect.
878  */
879  static int_fast32_t transtime(const int year, const struct rule *const rulep, const int_fast32_t offset) {
880  int leapyear;
881  int_fast32_t value;
882  int d, m1, yy0, yy1, yy2, dow;
883 
884  INITIALIZE(value);
885  leapyear = isleap(year);
886  switch (rulep->r_type) {
887 
888  case JULIAN_DAY:
889  /*
890  ** Jn - Julian day, 1 == January 1, 60 == March 1 even in leap
891  ** years.
892  ** In non-leap years, or if the day number is 59 or less, just
893  ** add SECSPERDAY times the day number-1 to the time of
894  ** January 1, midnight, to get the day.
895  */
896  value = (rulep->r_day - 1) * SECSPERDAY;
897  if (leapyear && rulep->r_day >= 60)
898  value += SECSPERDAY;
899  break;
900 
901  case DAY_OF_YEAR:
902  /*
903  ** n - day of year.
904  ** Just add SECSPERDAY times the day number to the time of
905  ** January 1, midnight, to get the day.
906  */
907  value = rulep->r_day * SECSPERDAY;
908  break;
909 
911  /*
912  ** Mm.n.d - nth "dth day" of month m.
913  */
914 
915  /*
916  ** Use Zeller's Congruence to get day-of-week of first day of
917  ** month.
918  */
919  m1 = (rulep->r_mon + 9) % 12 + 1;
920  yy0 = (rulep->r_mon <= 2) ? (year - 1) : year;
921  yy1 = yy0 / 100;
922  yy2 = yy0 % 100;
923  dow = ((26 * m1 - 2) / 10 +
924  1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7;
925  if (dow < 0)
926  dow += DAYSPERWEEK;
927 
928  /*
929  ** "dow" is the day-of-week of the first day of the month. Get
930  ** the day-of-month (zero-origin) of the first "dow" day of the
931  ** month.
932  */
933  d = rulep->r_day - dow;
934  if (d < 0)
935  d += DAYSPERWEEK;
936  for (int i = 1; i < rulep->r_week; ++i) {
937  if (d + DAYSPERWEEK >=
938  mon_lengths[leapyear][rulep->r_mon - 1])
939  break;
940  d += DAYSPERWEEK;
941  }
942 
943  /*
944  ** "d" is the day-of-month (zero-origin) of the day we want.
945  */
946  value = d * SECSPERDAY;
947  for (int i = 0; i < rulep->r_mon - 1; ++i)
948  value += mon_lengths[leapyear][i] * SECSPERDAY;
949  break;
950  }
951 
952  /*
953  ** "value" is the year-relative time of 00:00:00 UT on the day in
954  ** question. To get the year-relative time of the specified local
955  ** time on that day, add the transition time and the current offset
956  ** from UT.
957  */
958  return value + rulep->r_time + offset;
959  }
960 
961  /*
962  ** Given a POSIX section 8-style TZ string, fill in the rule tables as
963  ** appropriate.
964  */
965 
966  static int tzparse(const char * name, struct state * const sp, const int lastditch) {
967  const char * stdname;
968  const char * dstname;
969  size_t stdlen;
970  size_t dstlen;
971  int_fast32_t stdoffset;
972  int_fast32_t dstoffset;
973  char * cp;
974  int load_result;
975  static struct ttinfo zttinfo;
976 
977  INITIALIZE(dstname);
978  stdname = name;
979  if (lastditch) {
980  stdlen = strlen(name); /* length of standard zone name */
981  name += stdlen;
982  if (stdlen >= sizeof sp->chars)
983  stdlen = (sizeof sp->chars) - 1;
984  stdoffset = 0;
985  } else {
986  if (*name == '<') {
987  name++;
988  stdname = name;
989  name = getqzname(name, '>');
990  if (*name != '>')
991  return (-1);
992  stdlen = name - stdname;
993  name++;
994  } else {
995  name = getzname(name);
996  stdlen = name - stdname;
997  }
998  if (*name == '\0')
999  return -1;
1000  name = getoffset(name, &stdoffset);
1001  if (name == NULL)
1002  return -1;
1003  }
1004  load_result = tzload(TZDEFRULES, sp, FALSE);
1005  if (load_result != 0)
1006  sp->leapcnt = 0; /* so, we're off a little */
1007  if (*name != '\0') {
1008  if (*name == '<') {
1009  dstname = ++name;
1010  name = getqzname(name, '>');
1011  if (*name != '>')
1012  return -1;
1013  dstlen = name - dstname;
1014  name++;
1015  } else {
1016  dstname = name;
1017  name = getzname(name);
1018  dstlen = name - dstname; /* length of DST zone name */
1019  }
1020  if (*name != '\0' && *name != ',' && *name != ';') {
1021  name = getoffset(name, &dstoffset);
1022  if (name == NULL)
1023  return -1;
1024  } else dstoffset = stdoffset - SECSPERHOUR;
1025  if (*name == '\0' && load_result != 0)
1026  name = TZDEFRULESTRING;
1027  if (*name == ',' || *name == ';') {
1028  struct rule start;
1029  struct rule end;
1030  int year;
1031  int yearlim;
1032  int timecnt;
1033  time_t janfirst;
1034 
1035  ++name;
1036  if ((name = getrule(name, &start)) == NULL)
1037  return -1;
1038  if (*name++ != ',')
1039  return -1;
1040  if ((name = getrule(name, &end)) == NULL)
1041  return -1;
1042  if (*name != '\0')
1043  return -1;
1044  sp->typecnt = 2; /* standard time and DST */
1045  /*
1046  ** Two transitions per year, from EPOCH_YEAR forward.
1047  */
1048  sp->ttis[0] = sp->ttis[1] = zttinfo;
1049  sp->ttis[0].tt_gmtoff = -dstoffset;
1050  sp->ttis[0].tt_isdst = 1;
1051  sp->ttis[0].tt_abbrind = (int)(stdlen + 1);
1052  sp->ttis[1].tt_gmtoff = -stdoffset;
1053  sp->ttis[1].tt_isdst = 0;
1054  sp->ttis[1].tt_abbrind = 0;
1055  timecnt = 0;
1056  janfirst = 0;
1057  yearlim = EPOCH_YEAR + YEARSPERREPEAT;
1058  for (year = EPOCH_YEAR; year < yearlim; year++) {
1059  int_fast32_t
1060  starttime = transtime(year, &start, stdoffset),
1061  endtime = transtime(year, &end, dstoffset);
1062  int_fast32_t
1063  yearsecs = (year_lengths[isleap(year)]
1064  * SECSPERDAY);
1065  int reversed = endtime < starttime;
1066  if (reversed) {
1067  int_fast32_t swap = starttime;
1068  starttime = endtime;
1069  endtime = swap;
1070  }
1071  if (reversed
1072  || (starttime < endtime
1073  && (endtime - starttime
1074  < (yearsecs
1075  + (stdoffset - dstoffset))))) {
1076  if (TZ_MAX_TIMES - 2 < timecnt)
1077  break;
1078  yearlim = year + YEARSPERREPEAT + 1;
1079  sp->ats[timecnt] = janfirst;
1081  (&sp->ats[timecnt], starttime))
1082  break;
1083  sp->types[timecnt++] = (unsigned char) reversed;
1084  sp->ats[timecnt] = janfirst;
1086  (&sp->ats[timecnt], endtime))
1087  break;
1088  sp->types[timecnt++] = !reversed;
1089  }
1090  if (increment_overflow_time(&janfirst, yearsecs))
1091  break;
1092  }
1093  sp->timecnt = timecnt;
1094  if (!timecnt)
1095  sp->typecnt = 1; /* Perpetual DST. */
1096  } else {
1097  int_fast32_t theirstdoffset, theirdstoffset, theiroffset;
1098  int isdst;
1099 
1100  if (*name != '\0')
1101  return -1;
1102  /*
1103  ** Initial values of theirstdoffset and theirdstoffset.
1104  */
1105  theirstdoffset = 0;
1106  for (int i = 0; i < sp->timecnt; ++i) {
1107  int j = sp->types[i];
1108  if (!sp->ttis[j].tt_isdst) {
1109  theirstdoffset =
1110  -sp->ttis[j].tt_gmtoff;
1111  break;
1112  }
1113  }
1114  theirdstoffset = 0;
1115  for (int i = 0; i < sp->timecnt; ++i) {
1116  int j = sp->types[i];
1117  if (sp->ttis[j].tt_isdst) {
1118  theirdstoffset =
1119  -sp->ttis[j].tt_gmtoff;
1120  break;
1121  }
1122  }
1123  /*
1124  ** Initially we're assumed to be in standard time.
1125  */
1126  isdst = FALSE;
1127  theiroffset = theirstdoffset;
1128  /*
1129  ** Now juggle transition times and types
1130  ** tracking offsets as you do.
1131  */
1132  for (int i = 0; i < sp->timecnt; ++i) {
1133  int j = sp->types[i];
1134  sp->types[i] = (unsigned char)sp->ttis[j].tt_isdst;
1135  if (sp->ttis[j].tt_ttisgmt) {
1136  /* No adjustment to transition time */
1137  } else {
1138  /*
1139  ** If summer time is in effect, and the
1140  ** transition time was not specified as
1141  ** standard time, add the summer time
1142  ** offset to the transition time;
1143  ** otherwise, add the standard time
1144  ** offset to the transition time.
1145  */
1146  /*
1147  ** Transitions from DST to DDST
1148  ** will effectively disappear since
1149  ** POSIX provides for only one DST
1150  ** offset.
1151  */
1152  if (isdst && !sp->ttis[j].tt_ttisstd) {
1153  sp->ats[i] += dstoffset -
1154  theirdstoffset;
1155  } else {
1156  sp->ats[i] += stdoffset -
1157  theirstdoffset;
1158  }
1159  }
1160  theiroffset = -sp->ttis[j].tt_gmtoff;
1161  if (sp->ttis[j].tt_isdst)
1162  theirdstoffset = theiroffset;
1163  else theirstdoffset = theiroffset;
1164  }
1165  /*
1166  ** Finally, fill in ttis.
1167  */
1168  sp->ttis[0] = sp->ttis[1] = zttinfo;
1169  sp->ttis[0].tt_gmtoff = -stdoffset;
1170  sp->ttis[0].tt_isdst = FALSE;
1171  sp->ttis[0].tt_abbrind = 0;
1172  sp->ttis[1].tt_gmtoff = -dstoffset;
1173  sp->ttis[1].tt_isdst = TRUE;
1174  sp->ttis[1].tt_abbrind = (int)(stdlen + 1);
1175  sp->typecnt = 2;
1176  }
1177  } else {
1178  dstlen = 0;
1179  sp->typecnt = 1; /* only standard time */
1180  sp->timecnt = 0;
1181  sp->ttis[0] = zttinfo;
1182  sp->ttis[0].tt_gmtoff = -stdoffset;
1183  sp->ttis[0].tt_isdst = 0;
1184  sp->ttis[0].tt_abbrind = 0;
1185  }
1186  sp->charcnt = (int)(stdlen + 1);
1187  if (dstlen != 0)
1188  sp->charcnt += dstlen + 1;
1189  if ((size_t) sp->charcnt > sizeof sp->chars)
1190  return -1;
1191  cp = sp->chars;
1192  (void) strncpy(cp, stdname, stdlen);
1193  cp += stdlen;
1194  *cp++ = '\0';
1195  if (dstlen != 0) {
1196  (void) strncpy(cp, dstname, dstlen);
1197  *(cp + dstlen) = '\0';
1198  }
1199  return 0;
1200  }
1201 
1202  static int typesequiv(const struct state * const sp, const int a, const int b) {
1203  int result;
1204 
1205  if (sp == NULL ||
1206  a < 0 || a >= sp->typecnt ||
1207  b < 0 || b >= sp->typecnt)
1208  result = FALSE;
1209  else {
1210  const struct ttinfo * ap = &sp->ttis[a];
1211  const struct ttinfo * bp = &sp->ttis[b];
1212  result = ap->tt_gmtoff == bp->tt_gmtoff &&
1213  ap->tt_isdst == bp->tt_isdst &&
1214  ap->tt_ttisstd == bp->tt_ttisstd &&
1215  ap->tt_ttisgmt == bp->tt_ttisgmt &&
1216  strcmp(&sp->chars[ap->tt_abbrind],
1217  &sp->chars[bp->tt_abbrind]) == 0;
1218  }
1219  return result;
1220  } // #nocov end
1221 
1222  static int leaps_thru_end_of(const int y) {
1223  return (y >= 0) ? (y / 4 - y / 100 + y / 400) :
1224  -(leaps_thru_end_of(-(y + 1)) + 1);
1225  }
1226 
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;
1230  time_t tdays;
1231  int idays; /* unsigned would be so 2003 */
1232  int_fast64_t rem;
1233  int y;
1234  const int * ip;
1235  int_fast64_t corr;
1236  int hit;
1237  int i;
1238 
1239  corr = 0;
1240  hit = 0;
1241  i = sp->leapcnt;
1242  while (--i >= 0) {
1243  lp = &sp->lsis[i]; // #nocov start
1244  if (*timep >= lp->ls_trans) {
1245  if (*timep == lp->ls_trans) {
1246  hit = ((i == 0 && lp->ls_corr > 0) ||
1247  lp->ls_corr > sp->lsis[i - 1].ls_corr);
1248  if (hit)
1249  while (i > 0 &&
1250  sp->lsis[i].ls_trans ==
1251  sp->lsis[i - 1].ls_trans + 1 &&
1252  sp->lsis[i].ls_corr ==
1253  sp->lsis[i - 1].ls_corr + 1) {
1254  ++hit;
1255  --i;
1256  }
1257  }
1258  corr = lp->ls_corr;
1259  break; // #nocov end
1260  }
1261  }
1262  y = EPOCH_YEAR;
1263  tdays = *timep / SECSPERDAY;
1264  rem = *timep - tdays * SECSPERDAY;
1265  while (tdays < 0 || tdays >= year_lengths[isleap(y)]) {
1266  int newy;
1267  time_t tdelta;
1268  int idelta;
1269  int leapdays;
1270 
1271  tdelta = tdays / DAYSPERLYEAR;
1272  if (! ((! TYPE_SIGNED(time_t) || INT_MIN <= tdelta)
1273  && tdelta <= INT_MAX))
1274  return NULL; // #nocov
1275  idelta = (int)tdelta;
1276  if (idelta == 0)
1277  idelta = (tdays < 0) ? -1 : 1;
1278  newy = y;
1279  if (increment_overflow(&newy, idelta))
1280  return NULL; // #nocov
1281  leapdays = leaps_thru_end_of(newy - 1) -
1282  leaps_thru_end_of(y - 1);
1283  tdays -= ((time_t) newy - y) * DAYSPERNYEAR;
1284  tdays -= leapdays;
1285  y = newy;
1286  }
1287  {
1288  int_fast32_t seconds;
1289 
1290  seconds = (int_fast32_t)(tdays * SECSPERDAY);
1291  tdays = seconds / SECSPERDAY;
1292  rem += seconds - tdays * SECSPERDAY;
1293  }
1294  /*
1295  ** Given the range, we can now fearlessly cast...
1296  */
1297  idays = (int)tdays;
1298  rem += offset - corr;
1299  while (rem < 0) { // #nocov start
1300  rem += SECSPERDAY;
1301  --idays;
1302  }
1303  while (rem >= SECSPERDAY) {
1304  rem -= SECSPERDAY;
1305  ++idays;
1306  }
1307  while (idays < 0) {
1308  if (increment_overflow(&y, -1))
1309  return NULL;
1310  idays += year_lengths[isleap(y)];
1311  }
1312  while (idays >= year_lengths[isleap(y)]) {
1313  idays -= year_lengths[isleap(y)];
1314  if (increment_overflow(&y, 1))
1315  return NULL; // #nocov end
1316  }
1317  // Previously we returned 'year + base', so keep behaviour
1318  // It seems like R now returns just 'year - 1900' (as libc does)
1319  // But better for continuity to do as before
1320  tmp->tm_year = y + TM_YEAR_BASE;
1321  if (increment_overflow(&tmp->tm_year, -TM_YEAR_BASE))
1322  return NULL; // #nocov
1323  tmp->tm_yday = idays;
1324  /*
1325  ** The "extra" mods below avoid overflow problems.
1326  */
1327  tmp->tm_wday = EPOCH_WDAY +
1328  ((y - EPOCH_YEAR) % DAYSPERWEEK) *
1330  leaps_thru_end_of(y - 1) -
1332  idays;
1333  tmp->tm_wday %= DAYSPERWEEK;
1334  if (tmp->tm_wday < 0)
1335  tmp->tm_wday += DAYSPERWEEK; // #nocov
1336  tmp->tm_hour = (int) (rem / SECSPERHOUR);
1337  rem %= SECSPERHOUR;
1338  tmp->tm_min = (int) (rem / SECSPERMIN);
1339  /*
1340  ** A positive leap second requires a special
1341  ** representation. This uses "... ??:59:60" et seq.
1342  */
1343  tmp->tm_sec = (int) (rem % SECSPERMIN) + hit;
1344  ip = mon_lengths[isleap(y)];
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);
1348  tmp->tm_isdst = 0;
1349 #if ! (defined(__MINGW32__) || defined(__MINGW64__) || defined(__sun) || defined(sun) || defined(_AIX))
1350 //#ifdef HAVE_TM_GMTOFF
1351  tmp->tm_gmtoff = offset;
1352 #endif
1353  return tmp;
1354  }
1355 
1356  static void gmtload(struct state * const sp) {
1357  if (tzload(gmt, sp, TRUE) != 0)
1358  (void) tzparse(gmt, sp, TRUE);
1359  }
1360 
1361  /*
1362  ** gmtsub is to gmtime as localsub is to localtime.
1363  */
1364 
1365  static struct tm * gmtsub(const time_t *const timep, const int_fast32_t offset, struct tm *const tmp) {
1366  struct tm * result;
1367 
1368  if (!gmt_is_set) {
1369  gmt_is_set = TRUE;
1370  gmtload(gmtptr);
1371  }
1372  result = timesub(timep, offset, gmtptr, tmp);
1373  return result;
1374  }
1375 
1376  // [[Rcpp::register]]
1377  struct tm * gmtime_(const time_t * const timep) {
1378  return gmtsub(timep, 0L, &tm);
1379  }
1380 }
#define SECSPERDAY
Definition: date.cpp:298
#define TM_YEAR_BASE
Definition: date.cpp:322
#define SECSPERHOUR
Definition: date.cpp:297
#define DAYSPERNYEAR
Definition: date.cpp:295
#define MAXVAL(t, b)
Definition: date.cpp:154
#define is_digit(c)
Definition: date.cpp:148
#define SECSPERREPEAT
Definition: date.cpp:146
#define SECSPERMIN
Definition: date.cpp:291
#define TYPE_INTEGRAL(type)
Definition: date.cpp:141
#define MINVAL(t, b)
Definition: date.cpp:157
#define EPOCH_WDAY
Definition: date.cpp:325
#define MONSPERYEAR
Definition: date.cpp:299
#define DAY_OF_YEAR
Definition: date.cpp:417
#define days_in_year(year)
#define TZDEFRULESTRING
Definition: date.cpp:368
#define TZ_MAX_CHARS
Definition: date.cpp:283
#define BIGGEST(a, b)
Definition: date.cpp:371
#define HOURSPERDAY
Definition: date.cpp:293
#define JULIAN_DAY
Definition: date.cpp:416
#define isleap(y)
Definition: date.cpp:327
#define DAYSPERWEEK
Definition: date.cpp:294
#define EPOCH_YEAR
Definition: date.cpp:324
#define TZ_MAX_TYPES
Definition: date.cpp:270
#define MY_TZNAME_MAX
Definition: date.cpp:377
#define TZDEFRULES
Definition: date.cpp:196
#define MINSPERHOUR
Definition: date.cpp:292
#define INITIALIZE(x)
Definition: date.cpp:149
#define YEARSPERREPEAT
Definition: date.cpp:144
#define OPEN_MODE
Definition: date.cpp:355
#define TZ_MAX_TIMES
Definition: date.cpp:265
#define MONTH_NTH_DAY_OF_WEEK
Definition: date.cpp:418
#define gmtptr
Definition: date.cpp:434
#define DAYSPERLYEAR
Definition: date.cpp:296
#define TZ_MAX_LEAPS
Definition: date.cpp:288
#define TZDEFAULT
Definition: date.cpp:192
#define SECSPERREPEAT_BITS
Definition: date.cpp:147
#define TYPE_BIT(type)
Definition: date.cpp:139
#define TYPE_SIGNED(type)
Definition: date.cpp:140
Rcpp API.
Definition: algo.h:28
static const char * getoffset(const char *strp, int_fast32_t *const offsetp)
Definition: date.cpp:521
static const char * getnum(const char *strp, int *const nump, const int min, const int max)
Definition: date.cpp:568
static int_fast64_t detzcode64(const char *const codep)
Definition: date.cpp:489
static const char * getrule(const char *strp, struct rule *const rulep)
Definition: date.cpp:587
static const char * getsecs(const char *strp, int_fast32_t *secsp)
Definition: date.cpp:537
static struct tm * gmtsub(const time_t *const timep, const int_fast32_t offset, struct tm *const tmp)
Definition: date.cpp:1365
static int differ_by_repeat(const time_t t1, const time_t t0)
Definition: date.cpp:496
static int tzparse(const char *name, struct state *sp, int lastditch)
Definition: date.cpp:966
static int increment_overflow(int *const ip, int j)
Definition: date.cpp:453
static const char * getzname(const char *strp)
Definition: date.cpp:504
static const char gmt[]
Definition: date.cpp:358
static void gmtload(struct state *const sp)
Definition: date.cpp:1356
static int typesequiv(const struct state *sp, int a, int b)
Definition: date.cpp:1202
static struct tm tm
Definition: date.cpp:436
static time_t const time_t_max
Definition: date.cpp:162
static const int mon_lengths[2][MONSPERYEAR]
Definition: date.cpp:420
static int gmt_is_set
Definition: date.cpp:429
attribute_hidden struct tm * gmtime_(const time_t *const x)
Definition: routines.h:136
sugar::Max< RTYPE, NA, T > max(const VectorBase< RTYPE, NA, T > &x)
Definition: max.h:82
static const char * getqzname(const char *strp, const int delim)
Definition: date.cpp:513
static int leaps_thru_end_of(const int y)
Definition: date.cpp:1222
attribute_hidden double mktime00(struct tm &tm)
Definition: routines.h:130
static time_t const time_t_min
Definition: date.cpp:161
static struct tm * timesub(const time_t *timep, int_fast32_t offset, const struct state *sp, struct tm *tmp)
Definition: date.cpp:1227
static int increment_overflow_time(time_t *tp, int_fast32_t j)
Definition: date.cpp:468
static int_fast32_t detzcode(const char *const codep)
Definition: date.cpp:482
static struct state gmtmem
Definition: date.cpp:432
static int_fast32_t transtime(int year, const struct rule *rulep, int_fast32_t offset)
Definition: date.cpp:879
static const int year_lengths[2]
Definition: date.cpp:425
static int tzload(const char *name, struct state *const sp, const int doextend)
Definition: date.cpp:632
sugar::Min< RTYPE, NA, T > min(const VectorBase< RTYPE, NA, T > &x)
Definition: min.h:82
int_fast64_t ls_corr
Definition: date.cpp:390
time_t ls_trans
Definition: date.cpp:389
int_fast32_t r_time
Definition: date.cpp:413
int r_type
Definition: date.cpp:409
int r_week
Definition: date.cpp:411
int r_day
Definition: date.cpp:410
int r_mon
Definition: date.cpp:412
struct lsinfo lsis[TZ_MAX_LEAPS]
Definition: date.cpp:405
time_t ats[TZ_MAX_TIMES]
Definition: date.cpp:400
int timecnt
Definition: date.cpp:395
int goback
Definition: date.cpp:398
char chars[BIGGEST(BIGGEST(TZ_MAX_CHARS+1, sizeof gmt),(2 *(MY_TZNAME_MAX+1)))]
Definition: date.cpp:404
unsigned char types[TZ_MAX_TIMES]
Definition: date.cpp:401
int leapcnt
Definition: date.cpp:394
int typecnt
Definition: date.cpp:396
int goahead
Definition: date.cpp:399
struct ttinfo ttis[TZ_MAX_TYPES]
Definition: date.cpp:402
int charcnt
Definition: date.cpp:397
int tt_ttisstd
Definition: date.cpp:384
int tt_isdst
Definition: date.cpp:382
int tt_abbrind
Definition: date.cpp:383
int tt_ttisgmt
Definition: date.cpp:385
int_fast32_t tt_gmtoff
Definition: date.cpp:381
char tzh_ttisgmtcnt[4]
Definition: date.cpp:209
char tzh_charcnt[4]
Definition: date.cpp:214
char tzh_magic[4]
Definition: date.cpp:206
char tzh_leapcnt[4]
Definition: date.cpp:211
char tzh_reserved[15]
Definition: date.cpp:208
char tzh_timecnt[4]
Definition: date.cpp:212
char tzh_ttisstdcnt[4]
Definition: date.cpp:210
char tzh_typecnt[4]
Definition: date.cpp:213
char tzh_version[1]
Definition: date.cpp:207