PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
localtime.c File Reference
#include "c.h"
#include <fcntl.h>
#include "datatype/timestamp.h"
#include "pgtz.h"
#include "private.h"
#include "tzfile.h"
Include dependency graph for localtime.c:

Go to the source code of this file.

Data Structures

struct  rule
 
union  input_buffer
 
union  local_storage
 

Macros

#define WILDABBR   " "
 
#define TZDEFRULESTRING   ",M4.1.0,M10.5.0"
 
#define gmtptr   (&gmtmem)
 

Enumerations

enum  r_type { JULIAN_DAY, DAY_OF_YEAR, MONTH_NTH_DAY_OF_WEEK }
 

Functions

static struct pg_tmgmtsub (pg_time_t const *, int32, struct pg_tm *)
 
static bool increment_overflow (int *, int)
 
static bool increment_overflow_time (pg_time_t *, int32)
 
static struct pg_tmtimesub (pg_time_t const *, int32, struct state const *, struct pg_tm *)
 
static bool typesequiv (struct state const *, int, int)
 
static void init_ttinfo (struct ttinfo *s, int32 gmtoff, bool isdst, int abbrind)
 
static int32 detzcode (const char *codep)
 
static int64 detzcode64 (const char *codep)
 
static bool differ_by_repeat (const pg_time_t t1, const pg_time_t t0)
 
static int tzloadbody (char const *name, char *canonname, struct state *sp, bool doextend, union local_storage *lsp)
 
int tzload (const char *name, char *canonname, struct state *sp, bool doextend)
 
static const char * getzname (const char *strp)
 
static const char * getqzname (const char *strp, int delim)
 
static const char * getnum (const char *strp, int *nump, int min, int max)
 
static const char * getsecs (const char *strp, int32 *secsp)
 
static const char * getoffset (const char *strp, int32 *offsetp)
 
static const char * getrule (const char *strp, struct rule *rulep)
 
static int32 transtime (int year, const struct rule *rulep, int32 offset)
 
bool tzparse (const char *name, struct state *sp, bool lastditch)
 
static void gmtload (struct state *sp)
 
static struct pg_tmlocalsub (struct state const *sp, pg_time_t const *timep, struct pg_tm *tmp)
 
struct pg_tmpg_localtime (const pg_time_t *timep, const pg_tz *tz)
 
struct pg_tmpg_gmtime (const pg_time_t *timep)
 
static int leaps_thru_end_of (const int y)
 
int pg_next_dst_boundary (const pg_time_t *timep, long int *before_gmtoff, int *before_isdst, pg_time_t *boundary, long int *after_gmtoff, int *after_isdst, const pg_tz *tz)
 
bool pg_interpret_timezone_abbrev (const char *abbrev, const pg_time_t *timep, long int *gmtoff, int *isdst, const pg_tz *tz)
 
bool pg_get_timezone_offset (const pg_tz *tz, long int *gmtoff)
 
const char * pg_get_timezone_name (pg_tz *tz)
 
bool pg_tz_acceptable (pg_tz *tz)
 

Variables

static const char wildabbr [] = WILDABBR
 
static const char gmt [] = "GMT"
 
static const pg_time_t time_t_min = MINVAL(pg_time_t, TYPE_BIT(pg_time_t))
 
static const pg_time_t time_t_max = MAXVAL(pg_time_t, TYPE_BIT(pg_time_t))
 
static struct state tzdefrules_s
 
static int tzdefrules_loaded = 0
 
static struct pg_tm tm
 
static const int mon_lengths [2][MONSPERYEAR]
 
static const int year_lengths [2]
 

Macro Definition Documentation

#define gmtptr   (&gmtmem)

Referenced by gmtsub().

#define TZDEFRULESTRING   ",M4.1.0,M10.5.0"

Definition at line 71 of file localtime.c.

Referenced by tzparse().

#define WILDABBR   " "

Definition at line 46 of file localtime.c.

Enumeration Type Documentation

enum r_type
Enumerator
JULIAN_DAY 
DAY_OF_YEAR 
MONTH_NTH_DAY_OF_WEEK 

Definition at line 75 of file localtime.c.

76 {
77  JULIAN_DAY, /* Jn = Julian day */
78  DAY_OF_YEAR, /* n = day of year */
79  MONTH_NTH_DAY_OF_WEEK /* Mm.n.d = month, week, day of week */
80 };

Function Documentation

static int32 detzcode ( const char *  codep)
static

Definition at line 125 of file localtime.c.

References i, result, and TWOS_COMPLEMENT.

Referenced by tzloadbody().

126 {
127  int32 result;
128  int i;
129  int32 one = 1;
130  int32 halfmaxval = one << (32 - 2);
131  int32 maxval = halfmaxval - 1 + halfmaxval;
132  int32 minval = -1 - maxval;
133 
134  result = codep[0] & 0x7f;
135  for (i = 1; i < 4; ++i)
136  result = (result << 8) | (codep[i] & 0xff);
137 
138  if (codep[0] & 0x80)
139  {
140  /*
141  * Do two's-complement negation even on non-two's-complement machines.
142  * If the result would be minval - 1, return minval.
143  */
144  result -= !TWOS_COMPLEMENT(int32) &&result != 0;
145  result += minval;
146  }
147  return result;
148 }
return result
Definition: formatting.c:1633
signed int int32
Definition: c.h:256
int i
#define TWOS_COMPLEMENT(t)
Definition: private.h:72
static int64 detzcode64 ( const char *  codep)
static

Definition at line 151 of file localtime.c.

References i, result, and TWOS_COMPLEMENT.

Referenced by tzloadbody().

152 {
153  uint64 result;
154  int i;
155  int64 one = 1;
156  int64 halfmaxval = one << (64 - 2);
157  int64 maxval = halfmaxval - 1 + halfmaxval;
158  int64 minval = -TWOS_COMPLEMENT(int64) -maxval;
159 
160  result = codep[0] & 0x7f;
161  for (i = 1; i < 8; ++i)
162  result = (result << 8) | (codep[i] & 0xff);
163 
164  if (codep[0] & 0x80)
165  {
166  /*
167  * Do two's-complement negation even on non-two's-complement machines.
168  * If the result would be minval - 1, return minval.
169  */
170  result -= !TWOS_COMPLEMENT(int64) &&result != 0;
171  result += minval;
172  }
173  return result;
174 }
return result
Definition: formatting.c:1633
int i
#define TWOS_COMPLEMENT(t)
Definition: private.h:72
static bool differ_by_repeat ( const pg_time_t  t1,
const pg_time_t  t0 
)
static

Definition at line 177 of file localtime.c.

References SECSPERREPEAT, SECSPERREPEAT_BITS, TYPE_BIT, and TYPE_SIGNED.

Referenced by tzloadbody().

178 {
180  return 0;
181  return t1 - t0 == SECSPERREPEAT;
182 }
int64 pg_time_t
Definition: pgtime.h:23
#define SECSPERREPEAT_BITS
Definition: private.h:167
#define TYPE_BIT(type)
Definition: private.h:70
#define SECSPERREPEAT
Definition: private.h:165
#define TYPE_SIGNED(type)
Definition: private.h:71
static const char* getnum ( const char *  strp,
int *  nump,
int  min,
int  max 
)
static

Definition at line 645 of file localtime.c.

References is_digit, and NULL.

Referenced by getrule(), and getsecs().

646 {
647  char c;
648  int num;
649 
650  if (strp == NULL || !is_digit(c = *strp))
651  return NULL;
652  num = 0;
653  do
654  {
655  num = num * 10 + (c - '0');
656  if (num > max)
657  return NULL; /* illegal value */
658  c = *++strp;
659  } while (is_digit(c));
660  if (num < min)
661  return NULL; /* illegal value */
662  *nump = num;
663  return strp;
664 }
#define is_digit(c)
Definition: private.h:49
char * c
#define NULL
Definition: c.h:229
static const char* getoffset ( const char *  strp,
int32 offsetp 
)
static

Definition at line 714 of file localtime.c.

References getsecs(), and NULL.

Referenced by getrule(), and tzparse().

715 {
716  bool neg = false;
717 
718  if (*strp == '-')
719  {
720  neg = true;
721  ++strp;
722  }
723  else if (*strp == '+')
724  ++strp;
725  strp = getsecs(strp, offsetp);
726  if (strp == NULL)
727  return NULL; /* illegal time */
728  if (neg)
729  *offsetp = -*offsetp;
730  return strp;
731 }
static const char * getsecs(const char *strp, int32 *secsp)
Definition: localtime.c:674
#define NULL
Definition: c.h:229
static const char* getqzname ( const char *  strp,
int  delim 
)
static

Definition at line 629 of file localtime.c.

Referenced by tzparse().

630 {
631  int c;
632 
633  while ((c = *strp) != '\0' && c != delim)
634  ++strp;
635  return strp;
636 }
char * c
static const char* getrule ( const char *  strp,
struct rule rulep 
)
static

Definition at line 740 of file localtime.c.

References DAY_OF_YEAR, DAYSPERLYEAR, DAYSPERNYEAR, DAYSPERWEEK, getnum(), getoffset(), is_digit, JULIAN_DAY, MONSPERYEAR, MONTH_NTH_DAY_OF_WEEK, NULL, rule::r_day, rule::r_mon, rule::r_time, rule::r_type, rule::r_week, and SECSPERHOUR.

Referenced by tzparse().

741 {
742  if (*strp == 'J')
743  {
744  /*
745  * Julian day.
746  */
747  rulep->r_type = JULIAN_DAY;
748  ++strp;
749  strp = getnum(strp, &rulep->r_day, 1, DAYSPERNYEAR);
750  }
751  else if (*strp == 'M')
752  {
753  /*
754  * Month, week, day.
755  */
756  rulep->r_type = MONTH_NTH_DAY_OF_WEEK;
757  ++strp;
758  strp = getnum(strp, &rulep->r_mon, 1, MONSPERYEAR);
759  if (strp == NULL)
760  return NULL;
761  if (*strp++ != '.')
762  return NULL;
763  strp = getnum(strp, &rulep->r_week, 1, 5);
764  if (strp == NULL)
765  return NULL;
766  if (*strp++ != '.')
767  return NULL;
768  strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1);
769  }
770  else if (is_digit(*strp))
771  {
772  /*
773  * Day of year.
774  */
775  rulep->r_type = DAY_OF_YEAR;
776  strp = getnum(strp, &rulep->r_day, 0, DAYSPERLYEAR - 1);
777  }
778  else
779  return NULL; /* invalid format */
780  if (strp == NULL)
781  return NULL;
782  if (*strp == '/')
783  {
784  /*
785  * Time specified.
786  */
787  ++strp;
788  strp = getoffset(strp, &rulep->r_time);
789  }
790  else
791  rulep->r_time = 2 * SECSPERHOUR; /* default = 2:00:00 */
792  return strp;
793 }
static const char * getoffset(const char *strp, int32 *offsetp)
Definition: localtime.c:714
#define SECSPERHOUR
Definition: private.h:113
#define MONSPERYEAR
Definition: private.h:115
#define DAYSPERNYEAR
Definition: private.h:111
int r_mon
Definition: localtime.c:87
#define is_digit(c)
Definition: private.h:49
#define DAYSPERLYEAR
Definition: private.h:112
int r_week
Definition: localtime.c:86
#define DAYSPERWEEK
Definition: private.h:110
enum r_type r_type
Definition: localtime.c:84
int32 r_time
Definition: localtime.c:88
int r_day
Definition: localtime.c:85
#define NULL
Definition: c.h:229
static const char * getnum(const char *strp, int *nump, int min, int max)
Definition: localtime.c:645
static const char* getsecs ( const char *  strp,
int32 secsp 
)
static

Definition at line 674 of file localtime.c.

References DAYSPERWEEK, getnum(), HOURSPERDAY, MINSPERHOUR, NULL, SECSPERHOUR, and SECSPERMIN.

Referenced by getoffset().

675 {
676  int num;
677 
678  /*
679  * 'HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-Posix rules like
680  * "M10.4.6/26", which does not conform to Posix, but which specifies the
681  * equivalent of "02:00 on the first Sunday on or after 23 Oct".
682  */
683  strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1);
684  if (strp == NULL)
685  return NULL;
686  *secsp = num * (int32) SECSPERHOUR;
687  if (*strp == ':')
688  {
689  ++strp;
690  strp = getnum(strp, &num, 0, MINSPERHOUR - 1);
691  if (strp == NULL)
692  return NULL;
693  *secsp += num * SECSPERMIN;
694  if (*strp == ':')
695  {
696  ++strp;
697  /* 'SECSPERMIN' allows for leap seconds. */
698  strp = getnum(strp, &num, 0, SECSPERMIN);
699  if (strp == NULL)
700  return NULL;
701  *secsp += num;
702  }
703  }
704  return strp;
705 }
#define SECSPERMIN
Definition: private.h:107
#define SECSPERHOUR
Definition: private.h:113
#define HOURSPERDAY
Definition: private.h:109
signed int int32
Definition: c.h:256
#define DAYSPERWEEK
Definition: private.h:110
#define NULL
Definition: c.h:229
static const char * getnum(const char *strp, int *nump, int min, int max)
Definition: localtime.c:645
#define MINSPERHOUR
Definition: private.h:108
static const char* getzname ( const char *  strp)
static

Definition at line 610 of file localtime.c.

References is_digit.

Referenced by tzparse().

611 {
612  char c;
613 
614  while ((c = *strp) != '\0' && !is_digit(c) && c != ',' && c != '-' &&
615  c != '+')
616  ++strp;
617  return strp;
618 }
#define is_digit(c)
Definition: private.h:49
char * c
static void gmtload ( struct state sp)
static

Definition at line 1220 of file localtime.c.

References gmt, NULL, tzload(), and tzparse().

Referenced by gmtsub().

1221 {
1222  if (tzload(gmt, NULL, sp, true) != 0)
1223  tzparse(gmt, sp, true);
1224 }
int tzload(const char *name, char *canonname, struct state *sp, bool doextend)
Definition: localtime.c:556
bool tzparse(const char *name, struct state *sp, bool lastditch)
Definition: localtime.c:897
#define NULL
Definition: c.h:229
static const char gmt[]
Definition: localtime.c:51
static struct pg_tm * gmtsub ( pg_time_t const *  timep,
int32  offset,
struct pg_tm tmp 
)
static

Definition at line 1326 of file localtime.c.

References gmtload(), gmtptr, result, timesub(), pg_tm::tm_zone, and wildabbr.

Referenced by localsub(), and pg_gmtime().

1327 {
1328  struct pg_tm *result;
1329 
1330  /* GMT timezone state data is kept here */
1331  static struct state gmtmem;
1332  static bool gmt_is_set = false;
1333 #define gmtptr (&gmtmem)
1334 
1335  if (!gmt_is_set)
1336  {
1337  gmt_is_set = true;
1338  gmtload(gmtptr);
1339  }
1340  result = timesub(timep, offset, gmtptr, tmp);
1341 
1342  /*
1343  * Could get fancy here and deliver something such as "+xx" or "-xx" if
1344  * offset is non-zero, but this is no time for a treasure hunt.
1345  */
1346  if (offset != 0)
1347  tmp->tm_zone = wildabbr;
1348  else
1349  tmp->tm_zone = gmtptr->chars;
1350 
1351  return result;
1352 }
static void gmtload(struct state *sp)
Definition: localtime.c:1220
return result
Definition: formatting.c:1633
Definition: pgtime.h:25
static const char wildabbr[]
Definition: localtime.c:49
const char * tm_zone
Definition: pgtime.h:37
Definition: regguts.h:298
#define gmtptr
static struct pg_tm * timesub(pg_time_t const *, int32, struct state const *, struct pg_tm *)
Definition: localtime.c:1372
static bool increment_overflow ( int *  ip,
int  j 
)
static

Definition at line 1510 of file localtime.c.

References i.

Referenced by timesub().

1511 {
1512  int const i = *ip;
1513 
1514  /*----------
1515  * If i >= 0 there can only be overflow if i + j > INT_MAX
1516  * or if j > INT_MAX - i; given i >= 0, INT_MAX - i cannot overflow.
1517  * If i < 0 there can only be overflow if i + j < INT_MIN
1518  * or if j < INT_MIN - i; given i < 0, INT_MIN - i cannot overflow.
1519  *----------
1520  */
1521  if ((i >= 0) ? (j > INT_MAX - i) : (j < INT_MIN - i))
1522  return true;
1523  *ip += j;
1524  return false;
1525 }
int i
static bool increment_overflow_time ( pg_time_t tp,
int32  j 
)
static

Definition at line 1528 of file localtime.c.

References time_t_min, and TYPE_SIGNED.

Referenced by tzparse().

1529 {
1530  /*----------
1531  * This is like
1532  * 'if (! (time_t_min <= *tp + j && *tp + j <= time_t_max)) ...',
1533  * except that it does the right thing even if *tp + j would overflow.
1534  *----------
1535  */
1536  if (!(j < 0
1537  ? (TYPE_SIGNED(pg_time_t) ? time_t_min - j <= *tp : -1 - j < *tp)
1538  : *tp <= time_t_max - j))
1539  return true;
1540  *tp += j;
1541  return false;
1542 }
int64 pg_time_t
Definition: pgtime.h:23
static const pg_time_t time_t_max
Definition: localtime.c:55
static const pg_time_t time_t_min
Definition: localtime.c:54
#define TYPE_SIGNED(type)
Definition: private.h:71
static void init_ttinfo ( struct ttinfo s,
int32  gmtoff,
bool  isdst,
int  abbrind 
)
static

Definition at line 115 of file localtime.c.

References ttinfo::tt_abbrind, ttinfo::tt_gmtoff, ttinfo::tt_isdst, ttinfo::tt_ttisgmt, and ttinfo::tt_ttisstd.

Referenced by tzparse().

116 {
117  s->tt_gmtoff = gmtoff;
118  s->tt_isdst = isdst;
119  s->tt_abbrind = abbrind;
120  s->tt_ttisstd = false;
121  s->tt_ttisgmt = false;
122 }
int32 tt_gmtoff
Definition: pgtz.h:28
bool tt_isdst
Definition: pgtz.h:29
bool tt_ttisstd
Definition: pgtz.h:31
int tt_abbrind
Definition: pgtz.h:30
bool tt_ttisgmt
Definition: pgtz.h:32
static int leaps_thru_end_of ( const int  y)
static

Definition at line 1365 of file localtime.c.

Referenced by timesub().

1366 {
1367  return (y >= 0) ? (y / 4 - y / 100 + y / 400) :
1368  -(leaps_thru_end_of(-(y + 1)) + 1);
1369 }
static int leaps_thru_end_of(const int y)
Definition: localtime.c:1365
static struct pg_tm* localsub ( struct state const *  sp,
pg_time_t const *  timep,
struct pg_tm tmp 
)
static

Definition at line 1234 of file localtime.c.

References state::ats, AVGSECSPERYEAR, state::chars, state::defaulttype, gmtsub(), state::goahead, state::goback, i, NULL, result, SECSPERREPEAT, state::timecnt, timesub(), pg_tm::tm_isdst, pg_tm::tm_year, pg_tm::tm_zone, ttinfo::tt_abbrind, ttinfo::tt_gmtoff, ttinfo::tt_isdst, state::ttis, state::types, and YEARSPERREPEAT.

Referenced by pg_localtime().

1236 {
1237  const struct ttinfo *ttisp;
1238  int i;
1239  struct pg_tm *result;
1240  const pg_time_t t = *timep;
1241 
1242  if (sp == NULL)
1243  return gmtsub(timep, 0, tmp);
1244  if ((sp->goback && t < sp->ats[0]) ||
1245  (sp->goahead && t > sp->ats[sp->timecnt - 1]))
1246  {
1247  pg_time_t newt = t;
1248  pg_time_t seconds;
1249  pg_time_t years;
1250 
1251  if (t < sp->ats[0])
1252  seconds = sp->ats[0] - t;
1253  else
1254  seconds = t - sp->ats[sp->timecnt - 1];
1255  --seconds;
1256  years = (seconds / SECSPERREPEAT + 1) * YEARSPERREPEAT;
1257  seconds = years * AVGSECSPERYEAR;
1258  if (t < sp->ats[0])
1259  newt += seconds;
1260  else
1261  newt -= seconds;
1262  if (newt < sp->ats[0] ||
1263  newt > sp->ats[sp->timecnt - 1])
1264  return NULL; /* "cannot happen" */
1265  result = localsub(sp, &newt, tmp);
1266  if (result)
1267  {
1268  int64 newy;
1269 
1270  newy = result->tm_year;
1271  if (t < sp->ats[0])
1272  newy -= years;
1273  else
1274  newy += years;
1275  if (!(INT_MIN <= newy && newy <= INT_MAX))
1276  return NULL;
1277  result->tm_year = newy;
1278  }
1279  return result;
1280  }
1281  if (sp->timecnt == 0 || t < sp->ats[0])
1282  {
1283  i = sp->defaulttype;
1284  }
1285  else
1286  {
1287  int lo = 1;
1288  int hi = sp->timecnt;
1289 
1290  while (lo < hi)
1291  {
1292  int mid = (lo + hi) >> 1;
1293 
1294  if (t < sp->ats[mid])
1295  hi = mid;
1296  else
1297  lo = mid + 1;
1298  }
1299  i = (int) sp->types[lo - 1];
1300  }
1301  ttisp = &sp->ttis[i];
1302 
1303  result = timesub(&t, ttisp->tt_gmtoff, sp, tmp);
1304  if (result)
1305  {
1306  result->tm_isdst = ttisp->tt_isdst;
1307  result->tm_zone = (char *) &sp->chars[ttisp->tt_abbrind];
1308  }
1309  return result;
1310 }
#define AVGSECSPERYEAR
Definition: private.h:164
int64 pg_time_t
Definition: pgtime.h:23
int tm_isdst
Definition: pgtime.h:35
int32 tt_gmtoff
Definition: pgtz.h:28
Definition: pgtz.h:26
return result
Definition: formatting.c:1633
Definition: pgtime.h:25
bool tt_isdst
Definition: pgtz.h:29
const char * tm_zone
Definition: pgtime.h:37
#define NULL
Definition: c.h:229
#define YEARSPERREPEAT
Definition: private.h:105
int tm_year
Definition: pgtime.h:32
int tt_abbrind
Definition: pgtz.h:30
int i
static struct pg_tm * localsub(struct state const *sp, pg_time_t const *timep, struct pg_tm *tmp)
Definition: localtime.c:1234
#define SECSPERREPEAT
Definition: private.h:165
static struct pg_tm * timesub(pg_time_t const *, int32, struct state const *, struct pg_tm *)
Definition: localtime.c:1372
static struct pg_tm * gmtsub(pg_time_t const *, int32, struct pg_tm *)
Definition: localtime.c:1326
const char* pg_get_timezone_name ( pg_tz tz)

Definition at line 1830 of file localtime.c.

References NULL, and pg_tz::TZname.

Referenced by pg_timezone_names(), show_log_timezone(), and show_timezone().

1831 {
1832  if (tz)
1833  return tz->TZname;
1834  return NULL;
1835 }
#define NULL
Definition: c.h:229
char TZname[TZ_STRLEN_MAX+1]
Definition: pgtz.h:62
bool pg_get_timezone_offset ( const pg_tz tz,
long int *  gmtoff 
)

Definition at line 1806 of file localtime.c.

References i, pg_tz::state, ttinfo::tt_gmtoff, state::ttis, and state::typecnt.

Referenced by DecodeTimeOnly().

1807 {
1808  /*
1809  * The zone could have more than one ttinfo, if it's historically used
1810  * more than one abbreviation. We return true as long as they all have
1811  * the same gmtoff.
1812  */
1813  const struct state *sp;
1814  int i;
1815 
1816  sp = &tz->state;
1817  for (i = 1; i < sp->typecnt; i++)
1818  {
1819  if (sp->ttis[i].tt_gmtoff != sp->ttis[0].tt_gmtoff)
1820  return false;
1821  }
1822  *gmtoff = sp->ttis[0].tt_gmtoff;
1823  return true;
1824 }
int32 tt_gmtoff
Definition: pgtz.h:28
struct state state
Definition: pgtz.h:63
struct ttinfo ttis[TZ_MAX_TYPES]
Definition: pgtz.h:51
Definition: regguts.h:298
int i
int typecnt
Definition: pgtz.h:45
struct pg_tm* pg_gmtime ( const pg_time_t timep)

Definition at line 1355 of file localtime.c.

References gmtsub(), and tm.

Referenced by abstime2tm(), and GetEpochTime().

1356 {
1357  return gmtsub(timep, 0, &tm);
1358 }
static struct pg_tm tm
Definition: localtime.c:111
static struct pg_tm * gmtsub(pg_time_t const *, int32, struct pg_tm *)
Definition: localtime.c:1326
bool pg_interpret_timezone_abbrev ( const char *  abbrev,
const pg_time_t timep,
long int *  gmtoff,
int *  isdst,
const pg_tz tz 
)

Definition at line 1712 of file localtime.c.

References state::charcnt, charcnt, state::chars, i, pg_tz::state, state::timecnt, ttinfo::tt_abbrind, ttinfo::tt_gmtoff, ttinfo::tt_isdst, state::ttis, and state::types.

Referenced by DetermineTimeZoneAbbrevOffsetInternal().

1717 {
1718  const struct state *sp;
1719  const char *abbrs;
1720  const struct ttinfo *ttisp;
1721  int abbrind;
1722  int cutoff;
1723  int i;
1724  const pg_time_t t = *timep;
1725 
1726  sp = &tz->state;
1727 
1728  /*
1729  * Locate the abbreviation in the zone's abbreviation list. We assume
1730  * there are not duplicates in the list.
1731  */
1732  abbrs = sp->chars;
1733  abbrind = 0;
1734  while (abbrind < sp->charcnt)
1735  {
1736  if (strcmp(abbrev, abbrs + abbrind) == 0)
1737  break;
1738  while (abbrs[abbrind] != '\0')
1739  abbrind++;
1740  abbrind++;
1741  }
1742  if (abbrind >= sp->charcnt)
1743  return false; /* not there! */
1744 
1745  /*
1746  * Unlike pg_next_dst_boundary, we needn't sweat about extrapolation
1747  * (goback/goahead zones). Finding the newest or oldest meaning of the
1748  * abbreviation should get us what we want, since extrapolation would just
1749  * be repeating the newest or oldest meanings.
1750  *
1751  * Use binary search to locate the first transition > cutoff time.
1752  */
1753  {
1754  int lo = 0;
1755  int hi = sp->timecnt;
1756 
1757  while (lo < hi)
1758  {
1759  int mid = (lo + hi) >> 1;
1760 
1761  if (t < sp->ats[mid])
1762  hi = mid;
1763  else
1764  lo = mid + 1;
1765  }
1766  cutoff = lo;
1767  }
1768 
1769  /*
1770  * Scan backwards to find the latest interval using the given abbrev
1771  * before the cutoff time.
1772  */
1773  for (i = cutoff - 1; i >= 0; i--)
1774  {
1775  ttisp = &sp->ttis[sp->types[i]];
1776  if (ttisp->tt_abbrind == abbrind)
1777  {
1778  *gmtoff = ttisp->tt_gmtoff;
1779  *isdst = ttisp->tt_isdst;
1780  return true;
1781  }
1782  }
1783 
1784  /*
1785  * Not there, so scan forwards to find the first one after.
1786  */
1787  for (i = cutoff; i < sp->timecnt; i++)
1788  {
1789  ttisp = &sp->ttis[sp->types[i]];
1790  if (ttisp->tt_abbrind == abbrind)
1791  {
1792  *gmtoff = ttisp->tt_gmtoff;
1793  *isdst = ttisp->tt_isdst;
1794  return true;
1795  }
1796  }
1797 
1798  return false; /* hm, not actually used in any interval? */
1799 }
int64 pg_time_t
Definition: pgtime.h:23
int charcnt
Definition: pgtz.h:46
int32 tt_gmtoff
Definition: pgtz.h:28
Definition: pgtz.h:26
bool tt_isdst
Definition: pgtz.h:29
char chars[BIGGEST(BIGGEST(TZ_MAX_CHARS+1, 3),(2 *(TZ_STRLEN_MAX+1)))]
Definition: pgtz.h:53
struct state state
Definition: pgtz.h:63
struct ttinfo ttis[TZ_MAX_TYPES]
Definition: pgtz.h:51
unsigned char types[TZ_MAX_TIMES]
Definition: pgtz.h:50
Definition: regguts.h:298
int timecnt
Definition: pgtz.h:44
static int charcnt
Definition: zic.c:163
int tt_abbrind
Definition: pgtz.h:30
int i
struct pg_tm* pg_localtime ( const pg_time_t timep,
const pg_tz tz 
)

Definition at line 1314 of file localtime.c.

References localsub(), pg_tz::state, and tm.

Referenced by abstime2tm(), do_pg_start_backup(), do_pg_stop_backup(), log_line_prefix(), logfile_getname(), pg_tz_acceptable(), score_timezone(), set_next_rotation_time(), setup_formatted_log_time(), setup_formatted_start_time(), str_time(), timeofday(), timestamp2tm(), and timetz_zone().

1315 {
1316  return localsub(&tz->state, timep, &tm);
1317 }
static struct pg_tm tm
Definition: localtime.c:111
struct state state
Definition: pgtz.h:63
static struct pg_tm * localsub(struct state const *sp, pg_time_t const *timep, struct pg_tm *tmp)
Definition: localtime.c:1234
int pg_next_dst_boundary ( const pg_time_t timep,
long int *  before_gmtoff,
int *  before_isdst,
pg_time_t boundary,
long int *  after_gmtoff,
int *  after_isdst,
const pg_tz tz 
)

Definition at line 1565 of file localtime.c.

References state::ats, AVGSECSPERYEAR, state::goahead, state::goback, i, result, pg_tz::state, state::timecnt, ttinfo::tt_gmtoff, ttinfo::tt_isdst, state::ttis, state::typecnt, state::types, and YEARSPERREPEAT.

Referenced by DetermineTimeZoneOffsetInternal().

1572 {
1573  const struct state *sp;
1574  const struct ttinfo *ttisp;
1575  int i;
1576  int j;
1577  const pg_time_t t = *timep;
1578 
1579  sp = &tz->state;
1580  if (sp->timecnt == 0)
1581  {
1582  /* non-DST zone, use lowest-numbered standard type */
1583  i = 0;
1584  while (sp->ttis[i].tt_isdst)
1585  if (++i >= sp->typecnt)
1586  {
1587  i = 0;
1588  break;
1589  }
1590  ttisp = &sp->ttis[i];
1591  *before_gmtoff = ttisp->tt_gmtoff;
1592  *before_isdst = ttisp->tt_isdst;
1593  return 0;
1594  }
1595  if ((sp->goback && t < sp->ats[0]) ||
1596  (sp->goahead && t > sp->ats[sp->timecnt - 1]))
1597  {
1598  /* For values outside the transition table, extrapolate */
1599  pg_time_t newt = t;
1600  pg_time_t seconds;
1601  pg_time_t tcycles;
1602  int64 icycles;
1603  int result;
1604 
1605  if (t < sp->ats[0])
1606  seconds = sp->ats[0] - t;
1607  else
1608  seconds = t - sp->ats[sp->timecnt - 1];
1609  --seconds;
1610  tcycles = seconds / YEARSPERREPEAT / AVGSECSPERYEAR;
1611  ++tcycles;
1612  icycles = tcycles;
1613  if (tcycles - icycles >= 1 || icycles - tcycles >= 1)
1614  return -1;
1615  seconds = icycles;
1616  seconds *= YEARSPERREPEAT;
1617  seconds *= AVGSECSPERYEAR;
1618  if (t < sp->ats[0])
1619  newt += seconds;
1620  else
1621  newt -= seconds;
1622  if (newt < sp->ats[0] ||
1623  newt > sp->ats[sp->timecnt - 1])
1624  return -1; /* "cannot happen" */
1625 
1626  result = pg_next_dst_boundary(&newt, before_gmtoff,
1627  before_isdst,
1628  boundary,
1629  after_gmtoff,
1630  after_isdst,
1631  tz);
1632  if (t < sp->ats[0])
1633  *boundary -= seconds;
1634  else
1635  *boundary += seconds;
1636  return result;
1637  }
1638 
1639  if (t >= sp->ats[sp->timecnt - 1])
1640  {
1641  /* No known transition > t, so use last known segment's type */
1642  i = sp->types[sp->timecnt - 1];
1643  ttisp = &sp->ttis[i];
1644  *before_gmtoff = ttisp->tt_gmtoff;
1645  *before_isdst = ttisp->tt_isdst;
1646  return 0;
1647  }
1648  if (t < sp->ats[0])
1649  {
1650  /* For "before", use lowest-numbered standard type */
1651  i = 0;
1652  while (sp->ttis[i].tt_isdst)
1653  if (++i >= sp->typecnt)
1654  {
1655  i = 0;
1656  break;
1657  }
1658  ttisp = &sp->ttis[i];
1659  *before_gmtoff = ttisp->tt_gmtoff;
1660  *before_isdst = ttisp->tt_isdst;
1661  *boundary = sp->ats[0];
1662  /* And for "after", use the first segment's type */
1663  i = sp->types[0];
1664  ttisp = &sp->ttis[i];
1665  *after_gmtoff = ttisp->tt_gmtoff;
1666  *after_isdst = ttisp->tt_isdst;
1667  return 1;
1668  }
1669  /* Else search to find the boundary following t */
1670  {
1671  int lo = 1;
1672  int hi = sp->timecnt - 1;
1673 
1674  while (lo < hi)
1675  {
1676  int mid = (lo + hi) >> 1;
1677 
1678  if (t < sp->ats[mid])
1679  hi = mid;
1680  else
1681  lo = mid + 1;
1682  }
1683  i = lo;
1684  }
1685  j = sp->types[i - 1];
1686  ttisp = &sp->ttis[j];
1687  *before_gmtoff = ttisp->tt_gmtoff;
1688  *before_isdst = ttisp->tt_isdst;
1689  *boundary = sp->ats[i];
1690  j = sp->types[i];
1691  ttisp = &sp->ttis[j];
1692  *after_gmtoff = ttisp->tt_gmtoff;
1693  *after_isdst = ttisp->tt_isdst;
1694  return 1;
1695 }
#define AVGSECSPERYEAR
Definition: private.h:164
int64 pg_time_t
Definition: pgtime.h:23
bool goback
Definition: pgtz.h:47
int32 tt_gmtoff
Definition: pgtz.h:28
Definition: pgtz.h:26
return result
Definition: formatting.c:1633
pg_time_t ats[TZ_MAX_TIMES]
Definition: pgtz.h:49
bool tt_isdst
Definition: pgtz.h:29
struct state state
Definition: pgtz.h:63
struct ttinfo ttis[TZ_MAX_TYPES]
Definition: pgtz.h:51
unsigned char types[TZ_MAX_TIMES]
Definition: pgtz.h:50
int pg_next_dst_boundary(const pg_time_t *timep, long int *before_gmtoff, int *before_isdst, pg_time_t *boundary, long int *after_gmtoff, int *after_isdst, const pg_tz *tz)
Definition: localtime.c:1565
Definition: regguts.h:298
int timecnt
Definition: pgtz.h:44
#define YEARSPERREPEAT
Definition: private.h:105
int i
bool goahead
Definition: pgtz.h:48
int typecnt
Definition: pgtz.h:45
bool pg_tz_acceptable ( pg_tz tz)

Definition at line 1845 of file localtime.c.

References pg_localtime(), POSTGRES_EPOCH_JDATE, SECS_PER_DAY, pg_tm::tm_sec, and UNIX_EPOCH_JDATE.

Referenced by check_log_timezone(), check_timezone(), pg_tzenumerate_next(), score_timezone(), and validate_zone().

1846 {
1847  struct pg_tm *tt;
1848  pg_time_t time2000;
1849 
1850  /*
1851  * To detect leap-second timekeeping, run pg_localtime for what should be
1852  * GMT midnight, 2000-01-01. Insist that the tm_sec value be zero; any
1853  * other result has to be due to leap seconds.
1854  */
1856  tt = pg_localtime(&time2000, tz);
1857  if (!tt || tt->tm_sec != 0)
1858  return false;
1859 
1860  return true;
1861 }
struct pg_tm * pg_localtime(const pg_time_t *timep, const pg_tz *tz)
Definition: localtime.c:1314
int64 pg_time_t
Definition: pgtime.h:23
Definition: pgtime.h:25
#define SECS_PER_DAY
Definition: timestamp.h:86
#define UNIX_EPOCH_JDATE
Definition: timestamp.h:162
#define POSTGRES_EPOCH_JDATE
Definition: timestamp.h:163
int tm_sec
Definition: pgtime.h:27
static struct pg_tm * timesub ( pg_time_t const *  timep,
int32  offset,
struct state const *  sp,
struct pg_tm tmp 
)
static

Definition at line 1372 of file localtime.c.

References corr, DAYSPERLYEAR, DAYSPERNYEAR, DAYSPERWEEK, EOVERFLOW, EPOCH_WDAY, EPOCH_YEAR, i, increment_overflow(), isleap, state::leapcnt, leaps_thru_end_of(), lsinfo::ls_corr, lsinfo::ls_trans, state::lsis, NULL, SECSPERDAY, SECSPERHOUR, SECSPERMIN, pg_tm::tm_gmtoff, pg_tm::tm_hour, pg_tm::tm_isdst, pg_tm::tm_mday, pg_tm::tm_min, pg_tm::tm_mon, pg_tm::tm_sec, pg_tm::tm_wday, pg_tm::tm_yday, pg_tm::tm_year, TM_YEAR_BASE, and TYPE_SIGNED.

Referenced by gmtsub(), and localsub().

1374 {
1375  const struct lsinfo *lp;
1376  pg_time_t tdays;
1377  int idays; /* unsigned would be so 2003 */
1378  int64 rem;
1379  int y;
1380  const int *ip;
1381  int64 corr;
1382  bool hit;
1383  int i;
1384 
1385  corr = 0;
1386  hit = false;
1387  i = (sp == NULL) ? 0 : sp->leapcnt;
1388  while (--i >= 0)
1389  {
1390  lp = &sp->lsis[i];
1391  if (*timep >= lp->ls_trans)
1392  {
1393  if (*timep == lp->ls_trans)
1394  {
1395  hit = ((i == 0 && lp->ls_corr > 0) ||
1396  lp->ls_corr > sp->lsis[i - 1].ls_corr);
1397  if (hit)
1398  while (i > 0 &&
1399  sp->lsis[i].ls_trans ==
1400  sp->lsis[i - 1].ls_trans + 1 &&
1401  sp->lsis[i].ls_corr ==
1402  sp->lsis[i - 1].ls_corr + 1)
1403  {
1404  ++hit;
1405  --i;
1406  }
1407  }
1408  corr = lp->ls_corr;
1409  break;
1410  }
1411  }
1412  y = EPOCH_YEAR;
1413  tdays = *timep / SECSPERDAY;
1414  rem = *timep % SECSPERDAY;
1415  while (tdays < 0 || tdays >= year_lengths[isleap(y)])
1416  {
1417  int newy;
1418  pg_time_t tdelta;
1419  int idelta;
1420  int leapdays;
1421 
1422  tdelta = tdays / DAYSPERLYEAR;
1423  if (!((!TYPE_SIGNED(pg_time_t) ||INT_MIN <= tdelta)
1424  && tdelta <= INT_MAX))
1425  goto out_of_range;
1426  idelta = tdelta;
1427  if (idelta == 0)
1428  idelta = (tdays < 0) ? -1 : 1;
1429  newy = y;
1430  if (increment_overflow(&newy, idelta))
1431  goto out_of_range;
1432  leapdays = leaps_thru_end_of(newy - 1) -
1433  leaps_thru_end_of(y - 1);
1434  tdays -= ((pg_time_t) newy - y) * DAYSPERNYEAR;
1435  tdays -= leapdays;
1436  y = newy;
1437  }
1438 
1439  /*
1440  * Given the range, we can now fearlessly cast...
1441  */
1442  idays = tdays;
1443  rem += offset - corr;
1444  while (rem < 0)
1445  {
1446  rem += SECSPERDAY;
1447  --idays;
1448  }
1449  while (rem >= SECSPERDAY)
1450  {
1451  rem -= SECSPERDAY;
1452  ++idays;
1453  }
1454  while (idays < 0)
1455  {
1456  if (increment_overflow(&y, -1))
1457  goto out_of_range;
1458  idays += year_lengths[isleap(y)];
1459  }
1460  while (idays >= year_lengths[isleap(y)])
1461  {
1462  idays -= year_lengths[isleap(y)];
1463  if (increment_overflow(&y, 1))
1464  goto out_of_range;
1465  }
1466  tmp->tm_year = y;
1468  goto out_of_range;
1469  tmp->tm_yday = idays;
1470 
1471  /*
1472  * The "extra" mods below avoid overflow problems.
1473  */
1474  tmp->tm_wday = EPOCH_WDAY +
1475  ((y - EPOCH_YEAR) % DAYSPERWEEK) *
1477  leaps_thru_end_of(y - 1) -
1479  idays;
1480  tmp->tm_wday %= DAYSPERWEEK;
1481  if (tmp->tm_wday < 0)
1482  tmp->tm_wday += DAYSPERWEEK;
1483  tmp->tm_hour = (int) (rem / SECSPERHOUR);
1484  rem %= SECSPERHOUR;
1485  tmp->tm_min = (int) (rem / SECSPERMIN);
1486 
1487  /*
1488  * A positive leap second requires a special representation. This uses
1489  * "... ??:59:60" et seq.
1490  */
1491  tmp->tm_sec = (int) (rem % SECSPERMIN) + hit;
1492  ip = mon_lengths[isleap(y)];
1493  for (tmp->tm_mon = 0; idays >= ip[tmp->tm_mon]; ++(tmp->tm_mon))
1494  idays -= ip[tmp->tm_mon];
1495  tmp->tm_mday = (int) (idays + 1);
1496  tmp->tm_isdst = 0;
1497  tmp->tm_gmtoff = offset;
1498  return tmp;
1499 
1500 out_of_range:
1501  errno = EOVERFLOW;
1502  return NULL;
1503 }
#define SECSPERMIN
Definition: private.h:107
int64 pg_time_t
Definition: pgtime.h:23
int tm_wday
Definition: pgtime.h:33
int tm_isdst
Definition: pgtime.h:35
int tm_hour
Definition: pgtime.h:29
static zic_t corr[TZ_MAX_LEAPS]
Definition: zic.c:383
#define SECSPERDAY
Definition: private.h:114
#define isleap(y)
Definition: datetime.h:273
#define SECSPERHOUR
Definition: private.h:113
static const int mon_lengths[2][MONSPERYEAR]
Definition: localtime.c:595
#define DAYSPERNYEAR
Definition: private.h:111
long int tm_gmtoff
Definition: pgtime.h:36
#define DAYSPERLYEAR
Definition: private.h:112
#define TM_YEAR_BASE
Definition: private.h:138
#define DAYSPERWEEK
Definition: private.h:110
int64 ls_corr
Definition: pgtz.h:38
int tm_mday
Definition: pgtime.h:30
int tm_mon
Definition: pgtime.h:31
pg_time_t ls_trans
Definition: pgtz.h:37
#define EPOCH_YEAR
Definition: private.h:140
#define NULL
Definition: c.h:229
Definition: pgtz.h:35
#define EPOCH_WDAY
Definition: private.h:141
static int leaps_thru_end_of(const int y)
Definition: localtime.c:1365
static const int year_lengths[2]
Definition: localtime.c:600
static bool increment_overflow(int *, int)
Definition: localtime.c:1510
int tm_year
Definition: pgtime.h:32
int i
int tm_yday
Definition: pgtime.h:34
#define TYPE_SIGNED(type)
Definition: private.h:71
int tm_sec
Definition: pgtime.h:27
#define EOVERFLOW
Definition: private.h:38
int tm_min
Definition: pgtime.h:28
static int32 transtime ( int  year,
const struct rule rulep,
int32  offset 
)
static

Definition at line 800 of file localtime.c.

References DAY_OF_YEAR, DAYSPERWEEK, i, INITIALIZE, isleap, JULIAN_DAY, MONTH_NTH_DAY_OF_WEEK, rule::r_day, rule::r_mon, rule::r_time, rule::r_type, rule::r_week, SECSPERDAY, and value.

Referenced by tzparse().

802 {
803  bool leapyear;
804  int32 value;
805  int i,
806  d,
807  m1,
808  yy0,
809  yy1,
810  yy2,
811  dow;
812 
813  INITIALIZE(value);
814  leapyear = isleap(year);
815  switch (rulep->r_type)
816  {
817 
818  case JULIAN_DAY:
819 
820  /*
821  * Jn - Julian day, 1 == January 1, 60 == March 1 even in leap
822  * years. In non-leap years, or if the day number is 59 or less,
823  * just add SECSPERDAY times the day number-1 to the time of
824  * January 1, midnight, to get the day.
825  */
826  value = (rulep->r_day - 1) * SECSPERDAY;
827  if (leapyear && rulep->r_day >= 60)
828  value += SECSPERDAY;
829  break;
830 
831  case DAY_OF_YEAR:
832 
833  /*
834  * n - day of year. Just add SECSPERDAY times the day number to
835  * the time of January 1, midnight, to get the day.
836  */
837  value = rulep->r_day * SECSPERDAY;
838  break;
839 
841 
842  /*
843  * Mm.n.d - nth "dth day" of month m.
844  */
845 
846  /*
847  * Use Zeller's Congruence to get day-of-week of first day of
848  * month.
849  */
850  m1 = (rulep->r_mon + 9) % 12 + 1;
851  yy0 = (rulep->r_mon <= 2) ? (year - 1) : year;
852  yy1 = yy0 / 100;
853  yy2 = yy0 % 100;
854  dow = ((26 * m1 - 2) / 10 +
855  1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7;
856  if (dow < 0)
857  dow += DAYSPERWEEK;
858 
859  /*
860  * "dow" is the day-of-week of the first day of the month. Get the
861  * day-of-month (zero-origin) of the first "dow" day of the month.
862  */
863  d = rulep->r_day - dow;
864  if (d < 0)
865  d += DAYSPERWEEK;
866  for (i = 1; i < rulep->r_week; ++i)
867  {
868  if (d + DAYSPERWEEK >=
869  mon_lengths[(int) leapyear][rulep->r_mon - 1])
870  break;
871  d += DAYSPERWEEK;
872  }
873 
874  /*
875  * "d" is the day-of-month (zero-origin) of the day we want.
876  */
877  value = d * SECSPERDAY;
878  for (i = 0; i < rulep->r_mon - 1; ++i)
879  value += mon_lengths[(int) leapyear][i] * SECSPERDAY;
880  break;
881  }
882 
883  /*
884  * "value" is the year-relative time of 00:00:00 UT on the day in
885  * question. To get the year-relative time of the specified local time on
886  * that day, add the transition time and the current offset from UT.
887  */
888  return value + rulep->r_time + offset;
889 }
#define SECSPERDAY
Definition: private.h:114
#define isleap(y)
Definition: datetime.h:273
#define INITIALIZE(x)
Definition: private.h:98
static const int mon_lengths[2][MONSPERYEAR]
Definition: localtime.c:595
int r_mon
Definition: localtime.c:87
signed int int32
Definition: c.h:256
int r_week
Definition: localtime.c:86
#define DAYSPERWEEK
Definition: private.h:110
static struct @121 value
enum r_type r_type
Definition: localtime.c:84
int32 r_time
Definition: localtime.c:88
int r_day
Definition: localtime.c:85
int i
static bool typesequiv ( struct state const *  sp,
int  a,
int  b 
)
static

Definition at line 572 of file localtime.c.

References state::chars, NULL, result, ttinfo::tt_abbrind, ttinfo::tt_gmtoff, ttinfo::tt_isdst, ttinfo::tt_ttisgmt, ttinfo::tt_ttisstd, state::ttis, and state::typecnt.

Referenced by tzloadbody().

573 {
574  bool result;
575 
576  if (sp == NULL ||
577  a < 0 || a >= sp->typecnt ||
578  b < 0 || b >= sp->typecnt)
579  result = false;
580  else
581  {
582  const struct ttinfo *ap = &sp->ttis[a];
583  const struct ttinfo *bp = &sp->ttis[b];
584 
585  result = ap->tt_gmtoff == bp->tt_gmtoff &&
586  ap->tt_isdst == bp->tt_isdst &&
587  ap->tt_ttisstd == bp->tt_ttisstd &&
588  ap->tt_ttisgmt == bp->tt_ttisgmt &&
589  strcmp(&sp->chars[ap->tt_abbrind],
590  &sp->chars[bp->tt_abbrind]) == 0;
591  }
592  return result;
593 }
int32 tt_gmtoff
Definition: pgtz.h:28
Definition: pgtz.h:26
return result
Definition: formatting.c:1633
bool tt_isdst
Definition: pgtz.h:29
#define NULL
Definition: c.h:229
bool tt_ttisstd
Definition: pgtz.h:31
int tt_abbrind
Definition: pgtz.h:30
bool tt_ttisgmt
Definition: pgtz.h:32
int tzload ( const char *  name,
char *  canonname,
struct state sp,
bool  doextend 
)

Definition at line 556 of file localtime.c.

References free, malloc, and tzloadbody().

Referenced by gmtload(), pg_load_tz(), pg_tzenumerate_next(), pg_tzset(), and tzparse().

557 {
558  union local_storage *lsp = malloc(sizeof *lsp);
559 
560  if (!lsp)
561  return errno;
562  else
563  {
564  int err = tzloadbody(name, canonname, sp, doextend, lsp);
565 
566  free(lsp);
567  return err;
568  }
569 }
static int tzloadbody(char const *name, char *canonname, struct state *sp, bool doextend, union local_storage *lsp)
Definition: localtime.c:218
#define malloc(a)
Definition: header.h:50
#define free(a)
Definition: header.h:65
const char * name
Definition: encode.c:521
static int tzloadbody ( char const *  name,
char *  canonname,
struct state sp,
bool  doextend,
union local_storage lsp 
)
static

Definition at line 218 of file localtime.c.

References state::ats, input_buffer::buf, state::charcnt, charcnt, state::chars, close, corr, state::defaulttype, detzcode(), detzcode64(), differ_by_repeat(), state::goahead, state::goback, i, state::leapcnt, leapcnt, lsinfo::ls_corr, lsinfo::ls_trans, state::lsis, memmove, name, pg_open_tzfile(), read, time_t_max, time_t_min, state::timecnt, timecnt, trans, ttinfo::tt_abbrind, ttinfo::tt_gmtoff, ttinfo::tt_isdst, ttinfo::tt_ttisgmt, ttinfo::tt_ttisstd, state::ttis, TYPE_SIGNED, state::typecnt, typecnt, state::types, typesequiv(), TZ_MAX_CHARS, TZ_MAX_LEAPS, TZ_MAX_TIMES, TZ_MAX_TYPES, TZDEFAULT, tzhead::tzh_charcnt, tzhead::tzh_leapcnt, tzhead::tzh_timecnt, tzhead::tzh_ttisgmtcnt, tzhead::tzh_ttisstdcnt, tzhead::tzh_typecnt, tzhead::tzh_version, input_buffer::tzhead, tzparse(), and local_storage::u.

Referenced by tzload().

220 {
221  int i;
222  int fid;
223  int stored;
224  ssize_t nread;
225  union input_buffer *up = &lsp->u.u;
226  int tzheadsize = sizeof(struct tzhead);
227 
228  sp->goback = sp->goahead = false;
229 
230  if (!name)
231  {
232  name = TZDEFAULT;
233  if (!name)
234  return EINVAL;
235  }
236 
237  if (name[0] == ':')
238  ++name;
239 
240  fid = pg_open_tzfile(name, canonname);
241  if (fid < 0)
242  return ENOENT; /* pg_open_tzfile may not set errno */
243 
244  nread = read(fid, up->buf, sizeof up->buf);
245  if (nread < tzheadsize)
246  {
247  int err = nread < 0 ? errno : EINVAL;
248 
249  close(fid);
250  return err;
251  }
252  if (close(fid) < 0)
253  return errno;
254  for (stored = 4; stored <= 8; stored *= 2)
255  {
256  int32 ttisstdcnt = detzcode(up->tzhead.tzh_ttisstdcnt);
257  int32 ttisgmtcnt = detzcode(up->tzhead.tzh_ttisgmtcnt);
262  char const *p = up->buf + tzheadsize;
263 
264  if (!(0 <= leapcnt && leapcnt < TZ_MAX_LEAPS
265  && 0 < typecnt && typecnt < TZ_MAX_TYPES
266  && 0 <= timecnt && timecnt < TZ_MAX_TIMES
267  && 0 <= charcnt && charcnt < TZ_MAX_CHARS
268  && (ttisstdcnt == typecnt || ttisstdcnt == 0)
269  && (ttisgmtcnt == typecnt || ttisgmtcnt == 0)))
270  return EINVAL;
271  if (nread
272  < (tzheadsize /* struct tzhead */
273  + timecnt * stored /* ats */
274  + timecnt /* types */
275  + typecnt * 6 /* ttinfos */
276  + charcnt /* chars */
277  + leapcnt * (stored + 4) /* lsinfos */
278  + ttisstdcnt /* ttisstds */
279  + ttisgmtcnt)) /* ttisgmts */
280  return EINVAL;
281  sp->leapcnt = leapcnt;
282  sp->timecnt = timecnt;
283  sp->typecnt = typecnt;
284  sp->charcnt = charcnt;
285 
286  /*
287  * Read transitions, discarding those out of pg_time_t range. But
288  * pretend the last transition before time_t_min occurred at
289  * time_t_min.
290  */
291  timecnt = 0;
292  for (i = 0; i < sp->timecnt; ++i)
293  {
294  int64 at
295  = stored == 4 ? detzcode(p) : detzcode64(p);
296 
297  sp->types[i] = at <= time_t_max;
298  if (sp->types[i])
299  {
300  pg_time_t attime
301  = ((TYPE_SIGNED(pg_time_t) ? at < time_t_min : at < 0)
302  ? time_t_min : at);
303 
304  if (timecnt && attime <= sp->ats[timecnt - 1])
305  {
306  if (attime < sp->ats[timecnt - 1])
307  return EINVAL;
308  sp->types[i - 1] = 0;
309  timecnt--;
310  }
311  sp->ats[timecnt++] = attime;
312  }
313  p += stored;
314  }
315 
316  timecnt = 0;
317  for (i = 0; i < sp->timecnt; ++i)
318  {
319  unsigned char typ = *p++;
320 
321  if (sp->typecnt <= typ)
322  return EINVAL;
323  if (sp->types[i])
324  sp->types[timecnt++] = typ;
325  }
326  sp->timecnt = timecnt;
327  for (i = 0; i < sp->typecnt; ++i)
328  {
329  struct ttinfo *ttisp;
330  unsigned char isdst,
331  abbrind;
332 
333  ttisp = &sp->ttis[i];
334  ttisp->tt_gmtoff = detzcode(p);
335  p += 4;
336  isdst = *p++;
337  if (!(isdst < 2))
338  return EINVAL;
339  ttisp->tt_isdst = isdst;
340  abbrind = *p++;
341  if (!(abbrind < sp->charcnt))
342  return EINVAL;
343  ttisp->tt_abbrind = abbrind;
344  }
345  for (i = 0; i < sp->charcnt; ++i)
346  sp->chars[i] = *p++;
347  sp->chars[i] = '\0'; /* ensure '\0' at end */
348 
349  /* Read leap seconds, discarding those out of pg_time_t range. */
350  leapcnt = 0;
351  for (i = 0; i < sp->leapcnt; ++i)
352  {
353  int64 tr = stored == 4 ? detzcode(p) : detzcode64(p);
354  int32 corr = detzcode(p + stored);
355 
356  p += stored + 4;
357  if (tr <= time_t_max)
358  {
360  = ((TYPE_SIGNED(pg_time_t) ? tr < time_t_min : tr < 0)
361  ? time_t_min : tr);
362 
363  if (leapcnt && trans <= sp->lsis[leapcnt - 1].ls_trans)
364  {
365  if (trans < sp->lsis[leapcnt - 1].ls_trans)
366  return EINVAL;
367  leapcnt--;
368  }
369  sp->lsis[leapcnt].ls_trans = trans;
370  sp->lsis[leapcnt].ls_corr = corr;
371  leapcnt++;
372  }
373  }
374  sp->leapcnt = leapcnt;
375 
376  for (i = 0; i < sp->typecnt; ++i)
377  {
378  struct ttinfo *ttisp;
379 
380  ttisp = &sp->ttis[i];
381  if (ttisstdcnt == 0)
382  ttisp->tt_ttisstd = false;
383  else
384  {
385  if (*p != true && *p != false)
386  return EINVAL;
387  ttisp->tt_ttisstd = *p++;
388  }
389  }
390  for (i = 0; i < sp->typecnt; ++i)
391  {
392  struct ttinfo *ttisp;
393 
394  ttisp = &sp->ttis[i];
395  if (ttisgmtcnt == 0)
396  ttisp->tt_ttisgmt = false;
397  else
398  {
399  if (*p != true && *p != false)
400  return EINVAL;
401  ttisp->tt_ttisgmt = *p++;
402  }
403  }
404 
405  /*
406  * If this is an old file, we're done.
407  */
408  if (up->tzhead.tzh_version[0] == '\0')
409  break;
410  nread -= p - up->buf;
411  memmove(up->buf, p, nread);
412  }
413  if (doextend && nread > 2 &&
414  up->buf[0] == '\n' && up->buf[nread - 1] == '\n' &&
415  sp->typecnt + 2 <= TZ_MAX_TYPES)
416  {
417  struct state *ts = &lsp->u.st;
418 
419  up->buf[nread - 1] = '\0';
420  if (tzparse(&up->buf[1], ts, false)
421  && ts->typecnt == 2)
422  {
423  /*
424  * Attempt to reuse existing abbreviations. Without this,
425  * America/Anchorage would be right on the edge after 2037 when
426  * TZ_MAX_CHARS is 50, as sp->charcnt equals 40 (for LMT AST AWT
427  * APT AHST AHDT YST AKDT AKST) and ts->charcnt equals 10 (for
428  * AKST AKDT). Reusing means sp->charcnt can stay 40 in this
429  * example.
430  */
431  int gotabbr = 0;
432  int charcnt = sp->charcnt;
433 
434  for (i = 0; i < 2; i++)
435  {
436  char *tsabbr = ts->chars + ts->ttis[i].tt_abbrind;
437  int j;
438 
439  for (j = 0; j < charcnt; j++)
440  if (strcmp(sp->chars + j, tsabbr) == 0)
441  {
442  ts->ttis[i].tt_abbrind = j;
443  gotabbr++;
444  break;
445  }
446  if (!(j < charcnt))
447  {
448  int tsabbrlen = strlen(tsabbr);
449 
450  if (j + tsabbrlen < TZ_MAX_CHARS)
451  {
452  strcpy(sp->chars + j, tsabbr);
453  charcnt = j + tsabbrlen + 1;
454  ts->ttis[i].tt_abbrind = j;
455  gotabbr++;
456  }
457  }
458  }
459  if (gotabbr == 2)
460  {
461  sp->charcnt = charcnt;
462 
463  /*
464  * Ignore any trailing, no-op transitions generated by zic as
465  * they don't help here and can run afoul of bugs in zic 2016j
466  * or earlier.
467  */
468  while (1 < sp->timecnt
469  && (sp->types[sp->timecnt - 1]
470  == sp->types[sp->timecnt - 2]))
471  sp->timecnt--;
472 
473  for (i = 0; i < ts->timecnt; i++)
474  if (sp->ats[sp->timecnt - 1] < ts->ats[i])
475  break;
476  while (i < ts->timecnt
477  && sp->timecnt < TZ_MAX_TIMES)
478  {
479  sp->ats[sp->timecnt] = ts->ats[i];
480  sp->types[sp->timecnt] = (sp->typecnt
481  + ts->types[i]);
482  sp->timecnt++;
483  i++;
484  }
485  sp->ttis[sp->typecnt++] = ts->ttis[0];
486  sp->ttis[sp->typecnt++] = ts->ttis[1];
487  }
488  }
489  }
490  if (sp->timecnt > 1)
491  {
492  for (i = 1; i < sp->timecnt; ++i)
493  if (typesequiv(sp, sp->types[i], sp->types[0]) &&
494  differ_by_repeat(sp->ats[i], sp->ats[0]))
495  {
496  sp->goback = true;
497  break;
498  }
499  for (i = sp->timecnt - 2; i >= 0; --i)
500  if (typesequiv(sp, sp->types[sp->timecnt - 1],
501  sp->types[i]) &&
502  differ_by_repeat(sp->ats[sp->timecnt - 1],
503  sp->ats[i]))
504  {
505  sp->goahead = true;
506  break;
507  }
508  }
509 
510  /*
511  * If type 0 is unused in transitions, it's the type to use for early
512  * times.
513  */
514  for (i = 0; i < sp->timecnt; ++i)
515  if (sp->types[i] == 0)
516  break;
517  i = i < sp->timecnt ? -1 : 0;
518 
519  /*
520  * Absent the above, if there are transition times and the first
521  * transition is to a daylight time find the standard type less than and
522  * closest to the type of the first transition.
523  */
524  if (i < 0 && sp->timecnt > 0 && sp->ttis[sp->types[0]].tt_isdst)
525  {
526  i = sp->types[0];
527  while (--i >= 0)
528  if (!sp->ttis[i].tt_isdst)
529  break;
530  }
531 
532  /*
533  * If no result yet, find the first standard type. If there is none, punt
534  * to type zero.
535  */
536  if (i < 0)
537  {
538  i = 0;
539  while (sp->ttis[i].tt_isdst)
540  if (++i >= sp->typecnt)
541  {
542  i = 0;
543  break;
544  }
545  }
546  sp->defaulttype = i;
547  return 0;
548 }
#define TZDEFAULT
Definition: tzfile.h:24
static int typecnt
Definition: zic.c:184
int64 pg_time_t
Definition: pgtime.h:23
int charcnt
Definition: pgtz.h:46
static int32 detzcode(const char *codep)
Definition: localtime.c:125
static zic_t corr[TZ_MAX_LEAPS]
Definition: zic.c:383
bool goback
Definition: pgtz.h:47
int32 tt_gmtoff
Definition: pgtz.h:28
int leapcnt
Definition: pgtz.h:43
Definition: pgtz.h:26
#define TZ_MAX_TIMES
Definition: tzfile.h:93
struct tzhead tzhead
Definition: localtime.c:188
char tzh_timecnt[4]
Definition: tzfile.h:41
pg_time_t ats[TZ_MAX_TIMES]
Definition: pgtz.h:49
signed int int32
Definition: c.h:256
#define TZ_MAX_LEAPS
Definition: tzfile.h:101
bool tt_isdst
Definition: pgtz.h:29
struct lsinfo lsis[TZ_MAX_LEAPS]
Definition: pgtz.h:54
static int64 detzcode64(const char *codep)
Definition: localtime.c:151
static const pg_time_t time_t_max
Definition: localtime.c:55
int64 ls_corr
Definition: pgtz.h:38
#define memmove(d, s, c)
Definition: c.h:1058
static const pg_time_t time_t_min
Definition: localtime.c:54
static int leapcnt
Definition: zic.c:167
pg_time_t ls_trans
Definition: pgtz.h:37
char tzh_leapcnt[4]
Definition: tzfile.h:40
static bool typesequiv(struct state const *, int, int)
Definition: localtime.c:572
bool tzparse(const char *name, struct state *sp, bool lastditch)
Definition: localtime.c:897
char chars[BIGGEST(BIGGEST(TZ_MAX_CHARS+1, 3),(2 *(TZ_STRLEN_MAX+1)))]
Definition: pgtz.h:53
#define TZ_MAX_CHARS
Definition: tzfile.h:98
char buf[2 *sizeof(struct tzhead)+2 *sizeof(struct state)+4 *TZ_MAX_TIMES]
Definition: localtime.c:192
struct ttinfo ttis[TZ_MAX_TYPES]
Definition: pgtz.h:51
unsigned char types[TZ_MAX_TIMES]
Definition: pgtz.h:50
Definition: tzfile.h:33
char tzh_typecnt[4]
Definition: tzfile.h:42
char tzh_version[1]
Definition: tzfile.h:36
char tzh_charcnt[4]
Definition: tzfile.h:43
Definition: regguts.h:298
static ptrdiff_t timecnt
Definition: zic.c:182
int timecnt
Definition: pgtz.h:44
static int charcnt
Definition: zic.c:163
bool tt_ttisstd
Definition: pgtz.h:31
const char * name
Definition: encode.c:521
union input_buffer u
Definition: localtime.c:204
static zic_t trans[TZ_MAX_LEAPS]
Definition: zic.c:382
#define TZ_MAX_TYPES
Definition: tzfile.h:96
int tt_abbrind
Definition: pgtz.h:30
char tzh_ttisstdcnt[4]
Definition: tzfile.h:39
int i
int pg_open_tzfile(const char *name, char *canonname)
Definition: findtimezone.c:64
bool tt_ttisgmt
Definition: pgtz.h:32
bool goahead
Definition: pgtz.h:48
#define TYPE_SIGNED(type)
Definition: private.h:71
#define close(a)
Definition: win32.h:12
int typecnt
Definition: pgtz.h:45
#define read(a, b, c)
Definition: win32.h:13
static bool differ_by_repeat(const pg_time_t t1, const pg_time_t t0)
Definition: localtime.c:177
int defaulttype
Definition: pgtz.h:55
char tzh_ttisgmtcnt[4]
Definition: tzfile.h:38
bool tzparse ( const char *  name,
struct state sp,
bool  lastditch 
)

Definition at line 897 of file localtime.c.

References state::ats, state::charcnt, charcnt, state::chars, state::defaulttype, EPOCH_YEAR, getoffset(), getqzname(), getrule(), getzname(), state::goahead, state::goback, i, increment_overflow_time(), init_ttinfo(), isleap, state::leapcnt, name, NULL, SECSPERDAY, SECSPERHOUR, swap, state::timecnt, timecnt, transtime(), ttinfo::tt_gmtoff, ttinfo::tt_isdst, ttinfo::tt_ttisgmt, ttinfo::tt_ttisstd, state::ttis, state::typecnt, state::types, TZ_MAX_TIMES, TZDEFRULES, tzdefrules_s, TZDEFRULESTRING, tzload(), and YEARSPERREPEAT.

Referenced by gmtload(), pg_load_tz(), pg_tzset(), and tzloadbody().

898 {
899  const char *stdname;
900  const char *dstname = NULL;
901  size_t stdlen;
902  size_t dstlen;
903  size_t charcnt;
904  int32 stdoffset;
905  int32 dstoffset;
906  char *cp;
907  bool load_ok;
908 
909  stdname = name;
910  if (lastditch)
911  {
912  /*
913  * This is intentionally somewhat different from the IANA code. We do
914  * not want to invoke tzload() in the lastditch case: we can't assume
915  * pg_open_tzfile() is sane yet, and we don't care about leap seconds
916  * anyway.
917  */
918  stdlen = strlen(name); /* length of standard zone name */
919  name += stdlen;
920  if (stdlen >= sizeof sp->chars)
921  stdlen = (sizeof sp->chars) - 1;
922  charcnt = stdlen + 1;
923  stdoffset = 0;
924  sp->goback = sp->goahead = false; /* simulate failed tzload() */
925  load_ok = false;
926  }
927  else
928  {
929  if (*name == '<')
930  {
931  name++;
932  stdname = name;
933  name = getqzname(name, '>');
934  if (*name != '>')
935  return false;
936  stdlen = name - stdname;
937  name++;
938  }
939  else
940  {
941  name = getzname(name);
942  stdlen = name - stdname;
943  }
944  if (*name == '\0') /* we allow empty STD abbrev, unlike IANA */
945  return false;
946  name = getoffset(name, &stdoffset);
947  if (name == NULL)
948  return false;
949  charcnt = stdlen + 1;
950  if (sizeof sp->chars < charcnt)
951  return false;
952 
953  /*
954  * This bit also differs from the IANA code, which doesn't make any
955  * attempt to avoid repetitive loadings of the TZDEFRULES zone.
956  */
957  if (tzdefrules_loaded == 0)
958  {
959  if (tzload(TZDEFRULES, NULL, &tzdefrules_s, false) == 0)
960  tzdefrules_loaded = 1;
961  else
962  tzdefrules_loaded = -1;
963  }
964  load_ok = (tzdefrules_loaded > 0);
965  if (load_ok)
966  memcpy(sp, &tzdefrules_s, sizeof(struct state));
967  }
968  if (!load_ok)
969  sp->leapcnt = 0; /* so, we're off a little */
970  if (*name != '\0')
971  {
972  if (*name == '<')
973  {
974  dstname = ++name;
975  name = getqzname(name, '>');
976  if (*name != '>')
977  return false;
978  dstlen = name - dstname;
979  name++;
980  }
981  else
982  {
983  dstname = name;
984  name = getzname(name);
985  dstlen = name - dstname; /* length of DST zone name */
986  }
987  if (!dstlen)
988  return false;
989  charcnt += dstlen + 1;
990  if (sizeof sp->chars < charcnt)
991  return false;
992  if (*name != '\0' && *name != ',' && *name != ';')
993  {
994  name = getoffset(name, &dstoffset);
995  if (name == NULL)
996  return false;
997  }
998  else
999  dstoffset = stdoffset - SECSPERHOUR;
1000  if (*name == '\0' && !load_ok)
1002  if (*name == ',' || *name == ';')
1003  {
1004  struct rule start;
1005  struct rule end;
1006  int year;
1007  int yearlim;
1008  int timecnt;
1009  pg_time_t janfirst;
1010  int32 janoffset = 0;
1011  int yearbeg;
1012 
1013  ++name;
1014  if ((name = getrule(name, &start)) == NULL)
1015  return false;
1016  if (*name++ != ',')
1017  return false;
1018  if ((name = getrule(name, &end)) == NULL)
1019  return false;
1020  if (*name != '\0')
1021  return false;
1022  sp->typecnt = 2; /* standard time and DST */
1023 
1024  /*
1025  * Two transitions per year, from EPOCH_YEAR forward.
1026  */
1027  init_ttinfo(&sp->ttis[0], -dstoffset, true, stdlen + 1);
1028  init_ttinfo(&sp->ttis[1], -stdoffset, false, 0);
1029  sp->defaulttype = 0;
1030  timecnt = 0;
1031  janfirst = 0;
1032  yearbeg = EPOCH_YEAR;
1033 
1034  do
1035  {
1036  int32 yearsecs
1037  = year_lengths[isleap(yearbeg - 1)] * SECSPERDAY;
1038 
1039  yearbeg--;
1040  if (increment_overflow_time(&janfirst, -yearsecs))
1041  {
1042  janoffset = -yearsecs;
1043  break;
1044  }
1045  } while (EPOCH_YEAR - YEARSPERREPEAT / 2 < yearbeg);
1046 
1047  yearlim = yearbeg + YEARSPERREPEAT + 1;
1048  for (year = yearbeg; year < yearlim; year++)
1049  {
1050  int32
1051  starttime = transtime(year, &start, stdoffset),
1052  endtime = transtime(year, &end, dstoffset);
1053  int32
1054  yearsecs = (year_lengths[isleap(year)]
1055  * SECSPERDAY);
1056  bool reversed = endtime < starttime;
1057 
1058  if (reversed)
1059  {
1060  int32 swap = starttime;
1061 
1062  starttime = endtime;
1063  endtime = swap;
1064  }
1065  if (reversed
1066  || (starttime < endtime
1067  && (endtime - starttime
1068  < (yearsecs
1069  + (stdoffset - dstoffset)))))
1070  {
1071  if (TZ_MAX_TIMES - 2 < timecnt)
1072  break;
1073  sp->ats[timecnt] = janfirst;
1075  (&sp->ats[timecnt],
1076  janoffset + starttime))
1077  sp->types[timecnt++] = reversed;
1078  else if (janoffset)
1079  sp->defaulttype = reversed;
1080  sp->ats[timecnt] = janfirst;
1082  (&sp->ats[timecnt],
1083  janoffset + endtime))
1084  {
1085  sp->types[timecnt++] = !reversed;
1086  yearlim = year + YEARSPERREPEAT + 1;
1087  }
1088  else if (janoffset)
1089  sp->defaulttype = !reversed;
1090  }
1092  (&janfirst, janoffset + yearsecs))
1093  break;
1094  janoffset = 0;
1095  }
1096  sp->timecnt = timecnt;
1097  if (!timecnt)
1098  sp->typecnt = 1; /* Perpetual DST. */
1099  else if (YEARSPERREPEAT < year - yearbeg)
1100  sp->goback = sp->goahead = true;
1101  }
1102  else
1103  {
1104  int32 theirstdoffset;
1105  int32 theirdstoffset;
1106  int32 theiroffset;
1107  bool isdst;
1108  int i;
1109  int j;
1110 
1111  if (*name != '\0')
1112  return false;
1113 
1114  /*
1115  * Initial values of theirstdoffset and theirdstoffset.
1116  */
1117  theirstdoffset = 0;
1118  for (i = 0; i < sp->timecnt; ++i)
1119  {
1120  j = sp->types[i];
1121  if (!sp->ttis[j].tt_isdst)
1122  {
1123  theirstdoffset =
1124  -sp->ttis[j].tt_gmtoff;
1125  break;
1126  }
1127  }
1128  theirdstoffset = 0;
1129  for (i = 0; i < sp->timecnt; ++i)
1130  {
1131  j = sp->types[i];
1132  if (sp->ttis[j].tt_isdst)
1133  {
1134  theirdstoffset =
1135  -sp->ttis[j].tt_gmtoff;
1136  break;
1137  }
1138  }
1139 
1140  /*
1141  * Initially we're assumed to be in standard time.
1142  */
1143  isdst = false;
1144  theiroffset = theirstdoffset;
1145 
1146  /*
1147  * Now juggle transition times and types tracking offsets as you
1148  * do.
1149  */
1150  for (i = 0; i < sp->timecnt; ++i)
1151  {
1152  j = sp->types[i];
1153  sp->types[i] = sp->ttis[j].tt_isdst;
1154  if (sp->ttis[j].tt_ttisgmt)
1155  {
1156  /* No adjustment to transition time */
1157  }
1158  else
1159  {
1160  /*
1161  * If summer time is in effect, and the transition time
1162  * was not specified as standard time, add the summer time
1163  * offset to the transition time; otherwise, add the
1164  * standard time offset to the transition time.
1165  */
1166 
1167  /*
1168  * Transitions from DST to DDST will effectively disappear
1169  * since POSIX provides for only one DST offset.
1170  */
1171  if (isdst && !sp->ttis[j].tt_ttisstd)
1172  {
1173  sp->ats[i] += dstoffset -
1174  theirdstoffset;
1175  }
1176  else
1177  {
1178  sp->ats[i] += stdoffset -
1179  theirstdoffset;
1180  }
1181  }
1182  theiroffset = -sp->ttis[j].tt_gmtoff;
1183  if (sp->ttis[j].tt_isdst)
1184  theirdstoffset = theiroffset;
1185  else
1186  theirstdoffset = theiroffset;
1187  }
1188 
1189  /*
1190  * Finally, fill in ttis.
1191  */
1192  init_ttinfo(&sp->ttis[0], -stdoffset, false, 0);
1193  init_ttinfo(&sp->ttis[1], -dstoffset, true, stdlen + 1);
1194  sp->typecnt = 2;
1195  sp->defaulttype = 0;
1196  }
1197  }
1198  else
1199  {
1200  dstlen = 0;
1201  sp->typecnt = 1; /* only standard time */
1202  sp->timecnt = 0;
1203  init_ttinfo(&sp->ttis[0], -stdoffset, false, 0);
1204  sp->defaulttype = 0;
1205  }
1206  sp->charcnt = charcnt;
1207  cp = sp->chars;
1208  memcpy(cp, stdname, stdlen);
1209  cp += stdlen;
1210  *cp++ = '\0';
1211  if (dstlen != 0)
1212  {
1213  memcpy(cp, dstname, dstlen);
1214  *(cp + dstlen) = '\0';
1215  }
1216  return true;
1217 }
#define swap(a, b)
Definition: qsort.c:94
static const char * getoffset(const char *strp, int32 *offsetp)
Definition: localtime.c:714
static void init_ttinfo(struct ttinfo *s, int32 gmtoff, bool isdst, int abbrind)
Definition: localtime.c:115
int64 pg_time_t
Definition: pgtime.h:23
int tzload(const char *name, char *canonname, struct state *sp, bool doextend)
Definition: localtime.c:556
int charcnt
Definition: pgtz.h:46
bool goback
Definition: pgtz.h:47
int32 tt_gmtoff
Definition: pgtz.h:28
#define SECSPERDAY
Definition: private.h:114
#define isleap(y)
Definition: datetime.h:273
int leapcnt
Definition: pgtz.h:43
static const char * getrule(const char *strp, struct rule *rulep)
Definition: localtime.c:740
#define SECSPERHOUR
Definition: private.h:113
#define TZ_MAX_TIMES
Definition: tzfile.h:93
pg_time_t ats[TZ_MAX_TIMES]
Definition: pgtz.h:49
#define TZDEFRULESTRING
Definition: localtime.c:71
Definition: localtime.c:82
signed int int32
Definition: c.h:256
bool tt_isdst
Definition: pgtz.h:29
static struct state tzdefrules_s
Definition: localtime.c:61
char chars[BIGGEST(BIGGEST(TZ_MAX_CHARS+1, 3),(2 *(TZ_STRLEN_MAX+1)))]
Definition: pgtz.h:53
static int32 transtime(int year, const struct rule *rulep, int32 offset)
Definition: localtime.c:800
#define EPOCH_YEAR
Definition: private.h:140
struct ttinfo ttis[TZ_MAX_TYPES]
Definition: pgtz.h:51
unsigned char types[TZ_MAX_TIMES]
Definition: pgtz.h:50
static int tzdefrules_loaded
Definition: localtime.c:62
#define NULL
Definition: c.h:229
Definition: regguts.h:298
#define TZDEFRULES
Definition: tzfile.h:25
static ptrdiff_t timecnt
Definition: zic.c:182
int timecnt
Definition: pgtz.h:44
static int charcnt
Definition: zic.c:163
bool tt_ttisstd
Definition: pgtz.h:31
const char * name
Definition: encode.c:521
#define YEARSPERREPEAT
Definition: private.h:105
static bool increment_overflow_time(pg_time_t *, int32)
Definition: localtime.c:1528
static const int year_lengths[2]
Definition: localtime.c:600
int i
bool tt_ttisgmt
Definition: pgtz.h:32
bool goahead
Definition: pgtz.h:48
static const char * getqzname(const char *strp, int delim)
Definition: localtime.c:629
int typecnt
Definition: pgtz.h:45
int defaulttype
Definition: pgtz.h:55
static const char * getzname(const char *strp)
Definition: localtime.c:610

Variable Documentation

const char gmt[] = "GMT"
static

Definition at line 51 of file localtime.c.

Referenced by gbt_tstz_compress(), and gmtload().

const int mon_lengths[2][MONSPERYEAR]
static
Initial value:
= {
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
}

Definition at line 595 of file localtime.c.

const pg_time_t time_t_max = MAXVAL(pg_time_t, TYPE_BIT(pg_time_t))
static

Definition at line 55 of file localtime.c.

Referenced by tzloadbody().

const pg_time_t time_t_min = MINVAL(pg_time_t, TYPE_BIT(pg_time_t))
static

Definition at line 54 of file localtime.c.

Referenced by increment_overflow_time(), and tzloadbody().

struct pg_tm tm
static

Definition at line 111 of file localtime.c.

Referenced by abstime_date(), abstime_timestamp(), abstime_timestamptz(), abstimein(), abstimeout(), build_time_t(), createBackupLabel(), date2timestamptz(), date_in(), date_out(), DCH_to_char(), gbt_num_compress(), GetSQLCurrentDate(), GetSQLCurrentTime(), GetSQLLocalTime(), identify_system_timezone(), interval_in(), interval_out(), interval_part(), interval_to_char(), interval_trunc(), locale_date_order(), pg_gmtime(), pg_localtime(), PGTYPESdate_defmt_asc(), PGTYPESdate_fmt_asc(), PGTYPESdate_from_asc(), PGTYPESdate_to_asc(), PGTYPESdate_today(), PGTYPESinterval_from_asc(), PGTYPESinterval_to_asc(), PGTYPEStimestamp_add_interval(), PGTYPEStimestamp_current(), PGTYPEStimestamp_defmt_scan(), PGTYPEStimestamp_fmt_asc(), PGTYPEStimestamp_from_asc(), PGTYPEStimestamp_to_asc(), ReadHead(), reltimein(), reltimeout(), score_timezone(), set_next_rotation_time(), SetEpochTimestamp(), tarOpen(), time_in(), time_out(), time_part(), time_timetz(), timestamp2timestamptz(), timestamp_abstime(), timestamp_age(), timestamp_date(), timestamp_in(), timestamp_out(), timestamp_part(), timestamp_pl_interval(), timestamp_recv(), timestamp_time(), timestamp_to_char(), timestamp_trunc(), timestamptz2timestamp(), timestamptz_abstime(), timestamptz_age(), timestamptz_date(), timestamptz_in(), timestamptz_out(), timestamptz_part(), timestamptz_pl_interval(), timestamptz_recv(), timestamptz_time(), timestamptz_timetz(), timestamptz_to_char(), timestamptz_to_str(), timestamptz_trunc(), timetz_in(), timetz_out(), timetz_part(), timetz_zone(), typenameTypeMod(), WriteHead(), and writezone().

int tzdefrules_loaded = 0
static

Definition at line 62 of file localtime.c.

struct state tzdefrules_s
static

Definition at line 61 of file localtime.c.

Referenced by tzparse().

const char wildabbr[] = WILDABBR
static

Definition at line 49 of file localtime.c.

Referenced by gmtsub().

const int year_lengths[2]
static
Initial value:
= {
}
#define DAYSPERNYEAR
Definition: private.h:111
#define DAYSPERLYEAR
Definition: private.h:112

Definition at line 600 of file localtime.c.