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