PostgreSQL Source Code  git master
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
 
struct  local_storage::file_analysis
 

Macros

#define WILDABBR   " "
 
#define TZDEFRULESTRING   ",M3.2.0,M11.1.0"
 

Enumerations

enum  r_type { JULIAN_DAY , DAY_OF_YEAR , MONTH_NTH_DAY_OF_WEEK }
 

Functions

static struct pg_tmgmtsub (pg_time_t const *timep, int32 offset, struct pg_tm *tmp)
 
static bool increment_overflow (int *ip, int j)
 
static bool increment_overflow_time (pg_time_t *tp, int32 j)
 
static int64 leapcorr (struct state const *sp, pg_time_t t)
 
static struct pg_tmtimesub (pg_time_t const *timep, int32 offset, struct state const *sp, struct pg_tm *tmp)
 
static bool typesequiv (struct state const *sp, int a, int b)
 
static void init_ttinfo (struct ttinfo *s, int32 utoff, bool isdst, int desigidx)
 
static int32 detzcode (const char *const codep)
 
static int64 detzcode64 (const char *const 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, const int delim)
 
static const char * getnum (const char *strp, int *const nump, const int min, const int max)
 
static const char * getsecs (const char *strp, int32 *const secsp)
 
static const char * getoffset (const char *strp, int32 *const offsetp)
 
static const char * getrule (const char *strp, struct rule *const rulep)
 
static int32 transtime (const int year, const struct rule *const rulep, const int32 offset)
 
bool tzparse (const char *name, struct state *sp, bool lastditch)
 
static void gmtload (struct state *const sp)
 
static struct pg_tmlocalsub (struct state const *sp, pg_time_t const *timep, struct pg_tm *const 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_nonneg (int y)
 
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 struct pg_tm tm
 
static const int mon_lengths [2][MONSPERYEAR]
 
static const int year_lengths [2]
 

Macro Definition Documentation

◆ TZDEFRULESTRING

#define TZDEFRULESTRING   ",M3.2.0,M11.1.0"

Definition at line 61 of file localtime.c.

◆ WILDABBR

#define WILDABBR   " "

Definition at line 48 of file localtime.c.

Enumeration Type Documentation

◆ r_type

enum r_type
Enumerator
JULIAN_DAY 
DAY_OF_YEAR 
MONTH_NTH_DAY_OF_WEEK 

Definition at line 65 of file localtime.c.

66 {
67  JULIAN_DAY, /* Jn = Julian day */
68  DAY_OF_YEAR, /* n = day of year */
69  MONTH_NTH_DAY_OF_WEEK, /* Mm.n.d = month, week, day of week */
70 };
@ JULIAN_DAY
Definition: localtime.c:67
@ MONTH_NTH_DAY_OF_WEEK
Definition: localtime.c:69
@ DAY_OF_YEAR
Definition: localtime.c:68

Function Documentation

◆ detzcode()

static int32 detzcode ( const char *const  codep)
static

Definition at line 118 of file localtime.c.

119 {
120  int32 result;
121  int i;
122  int32 one = 1;
123  int32 halfmaxval = one << (32 - 2);
124  int32 maxval = halfmaxval - 1 + halfmaxval;
125  int32 minval = -1 - maxval;
126 
127  result = codep[0] & 0x7f;
128  for (i = 1; i < 4; ++i)
129  result = (result << 8) | (codep[i] & 0xff);
130 
131  if (codep[0] & 0x80)
132  {
133  /*
134  * Do two's-complement negation even on non-two's-complement machines.
135  * If the result would be minval - 1, return minval.
136  */
137  result -= !TWOS_COMPLEMENT(int32) && result != 0;
138  result += minval;
139  }
140  return result;
141 }
signed int int32
Definition: c.h:481
int i
Definition: isn.c:73
#define TWOS_COMPLEMENT(t)
Definition: private.h:58

References i, and TWOS_COMPLEMENT.

Referenced by tzloadbody().

◆ detzcode64()

static int64 detzcode64 ( const char *const  codep)
static

Definition at line 144 of file localtime.c.

145 {
146  uint64 result;
147  int i;
148  int64 one = 1;
149  int64 halfmaxval = one << (64 - 2);
150  int64 maxval = halfmaxval - 1 + halfmaxval;
151  int64 minval = -TWOS_COMPLEMENT(int64) - maxval;
152 
153  result = codep[0] & 0x7f;
154  for (i = 1; i < 8; ++i)
155  result = (result << 8) | (codep[i] & 0xff);
156 
157  if (codep[0] & 0x80)
158  {
159  /*
160  * Do two's-complement negation even on non-two's-complement machines.
161  * If the result would be minval - 1, return minval.
162  */
163  result -= !TWOS_COMPLEMENT(int64) && result != 0;
164  result += minval;
165  }
166  return result;
167 }

References i, and TWOS_COMPLEMENT.

Referenced by tzloadbody().

◆ differ_by_repeat()

static bool differ_by_repeat ( const pg_time_t  t1,
const pg_time_t  t0 
)
static

Definition at line 170 of file localtime.c.

171 {
173  return 0;
174  return t1 - t0 == SECSPERREPEAT;
175 }
int64 pg_time_t
Definition: pgtime.h:23
#define SECSPERREPEAT
Definition: private.h:155
#define SECSPERREPEAT_BITS
Definition: private.h:157
#define TYPE_BIT(type)
Definition: private.h:56
#define TYPE_SIGNED(type)
Definition: private.h:57

References SECSPERREPEAT, SECSPERREPEAT_BITS, TYPE_BIT, and TYPE_SIGNED.

Referenced by tzloadbody().

◆ getnum()

static const char* getnum ( const char *  strp,
int *const  nump,
const int  min,
const int  max 
)
static

Definition at line 680 of file localtime.c.

681 {
682  char c;
683  int num;
684 
685  if (strp == NULL || !is_digit(c = *strp))
686  return NULL;
687  num = 0;
688  do
689  {
690  num = num * 10 + (c - '0');
691  if (num > max)
692  return NULL; /* illegal value */
693  c = *++strp;
694  } while (is_digit(c));
695  if (num < min)
696  return NULL; /* illegal value */
697  *nump = num;
698  return strp;
699 }
char * c
#define is_digit(c)
Definition: private.h:45

References is_digit.

Referenced by getrule(), and getsecs().

◆ getoffset()

static const char* getoffset ( const char *  strp,
int32 *const  offsetp 
)
static

Definition at line 751 of file localtime.c.

752 {
753  bool neg = false;
754 
755  if (*strp == '-')
756  {
757  neg = true;
758  ++strp;
759  }
760  else if (*strp == '+')
761  ++strp;
762  strp = getsecs(strp, offsetp);
763  if (strp == NULL)
764  return NULL; /* illegal time */
765  if (neg)
766  *offsetp = -*offsetp;
767  return strp;
768 }
static const char * getsecs(const char *strp, int32 *const secsp)
Definition: localtime.c:710

References getsecs().

Referenced by getrule(), and tzparse().

◆ getqzname()

static const char* getqzname ( const char *  strp,
const int  delim 
)
static

Definition at line 663 of file localtime.c.

664 {
665  int c;
666 
667  while ((c = *strp) != '\0' && c != delim)
668  ++strp;
669  return strp;
670 }

Referenced by tzparse().

◆ getrule()

static const char* getrule ( const char *  strp,
struct rule *const  rulep 
)
static

Definition at line 778 of file localtime.c.

779 {
780  if (*strp == 'J')
781  {
782  /*
783  * Julian day.
784  */
785  rulep->r_type = JULIAN_DAY;
786  ++strp;
787  strp = getnum(strp, &rulep->r_day, 1, DAYSPERNYEAR);
788  }
789  else if (*strp == 'M')
790  {
791  /*
792  * Month, week, day.
793  */
794  rulep->r_type = MONTH_NTH_DAY_OF_WEEK;
795  ++strp;
796  strp = getnum(strp, &rulep->r_mon, 1, MONSPERYEAR);
797  if (strp == NULL)
798  return NULL;
799  if (*strp++ != '.')
800  return NULL;
801  strp = getnum(strp, &rulep->r_week, 1, 5);
802  if (strp == NULL)
803  return NULL;
804  if (*strp++ != '.')
805  return NULL;
806  strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1);
807  }
808  else if (is_digit(*strp))
809  {
810  /*
811  * Day of year.
812  */
813  rulep->r_type = DAY_OF_YEAR;
814  strp = getnum(strp, &rulep->r_day, 0, DAYSPERLYEAR - 1);
815  }
816  else
817  return NULL; /* invalid format */
818  if (strp == NULL)
819  return NULL;
820  if (*strp == '/')
821  {
822  /*
823  * Time specified.
824  */
825  ++strp;
826  strp = getoffset(strp, &rulep->r_time);
827  }
828  else
829  rulep->r_time = 2 * SECSPERHOUR; /* default = 2:00:00 */
830  return strp;
831 }
static const char * getnum(const char *strp, int *const nump, const int min, const int max)
Definition: localtime.c:680
static const char * getoffset(const char *strp, int32 *const offsetp)
Definition: localtime.c:751
#define SECSPERHOUR
Definition: private.h:103
#define DAYSPERNYEAR
Definition: private.h:101
#define MONSPERYEAR
Definition: private.h:105
#define DAYSPERWEEK
Definition: private.h:100
#define DAYSPERLYEAR
Definition: private.h:102
int32 r_time
Definition: localtime.c:78
enum r_type r_type
Definition: localtime.c:74
int r_mon
Definition: localtime.c:77
int r_day
Definition: localtime.c:75
int r_week
Definition: localtime.c:76

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

Referenced by tzparse().

◆ getsecs()

static const char* getsecs ( const char *  strp,
int32 *const  secsp 
)
static

Definition at line 710 of file localtime.c.

711 {
712  int num;
713 
714  /*
715  * 'HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-Posix rules like
716  * "M10.4.6/26", which does not conform to Posix, but which specifies the
717  * equivalent of "02:00 on the first Sunday on or after 23 Oct".
718  */
719  strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1);
720  if (strp == NULL)
721  return NULL;
722  *secsp = num * (int32) SECSPERHOUR;
723  if (*strp == ':')
724  {
725  ++strp;
726  strp = getnum(strp, &num, 0, MINSPERHOUR - 1);
727  if (strp == NULL)
728  return NULL;
729  *secsp += num * SECSPERMIN;
730  if (*strp == ':')
731  {
732  ++strp;
733  /* 'SECSPERMIN' allows for leap seconds. */
734  strp = getnum(strp, &num, 0, SECSPERMIN);
735  if (strp == NULL)
736  return NULL;
737  *secsp += num;
738  }
739  }
740  return strp;
741 }
#define SECSPERMIN
Definition: private.h:97
#define HOURSPERDAY
Definition: private.h:99
#define MINSPERHOUR
Definition: private.h:98

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

Referenced by getoffset().

◆ getzname()

static const char* getzname ( const char *  strp)
static

Definition at line 642 of file localtime.c.

643 {
644  char c;
645 
646  while ((c = *strp) != '\0' && !is_digit(c) && c != ',' && c != '-' &&
647  c != '+')
648  ++strp;
649  return strp;
650 }

References is_digit.

Referenced by tzparse().

◆ gmtload()

static void gmtload ( struct state *const  sp)
static

Definition at line 1245 of file localtime.c.

1246 {
1247  if (tzload(gmt, NULL, sp, true) != 0)
1248  tzparse(gmt, sp, true);
1249 }
int tzload(const char *name, char *canonname, struct state *sp, bool doextend)
Definition: localtime.c:586
static const char gmt[]
Definition: localtime.c:53
bool tzparse(const char *name, struct state *sp, bool lastditch)
Definition: localtime.c:936

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

Referenced by gmtsub().

◆ gmtsub()

static struct pg_tm * gmtsub ( pg_time_t const *  timep,
int32  offset,
struct pg_tm tmp 
)
static

Definition at line 1357 of file localtime.c.

1359 {
1360  struct pg_tm *result;
1361 
1362  /* GMT timezone state data is kept here */
1363  static struct state *gmtptr = NULL;
1364 
1365  if (gmtptr == NULL)
1366  {
1367  /* Allocate on first use */
1368  gmtptr = (struct state *) malloc(sizeof(struct state));
1369  if (gmtptr == NULL)
1370  return NULL; /* errno should be set by malloc */
1371  gmtload(gmtptr);
1372  }
1373 
1374  result = timesub(timep, offset, gmtptr, tmp);
1375 
1376  /*
1377  * Could get fancy here and deliver something such as "+xx" or "-xx" if
1378  * offset is non-zero, but this is no time for a treasure hunt.
1379  */
1380  if (offset != 0)
1381  tmp->tm_zone = wildabbr;
1382  else
1383  tmp->tm_zone = gmtptr->chars;
1384 
1385  return result;
1386 }
#define malloc(a)
Definition: header.h:50
static void gmtload(struct state *const sp)
Definition: localtime.c:1245
static struct pg_tm * timesub(pg_time_t const *timep, int32 offset, struct state const *sp, struct pg_tm *tmp)
Definition: localtime.c:1414
static const char wildabbr[]
Definition: localtime.c:51
Definition: pgtime.h:35
Definition: regguts.h:323
char chars[BIGGEST(BIGGEST(TZ_MAX_CHARS+1, 4),(2 *(TZ_STRLEN_MAX+1)))]
Definition: pgtz.h:53
struct state * tmp
Definition: regguts.h:331

References state::chars, gmtload(), malloc, timesub(), state::tmp, and wildabbr.

Referenced by localsub(), and pg_gmtime().

◆ increment_overflow()

static bool increment_overflow ( int *  ip,
int  j 
)
static

Definition at line 1539 of file localtime.c.

1540 {
1541  int const i = *ip;
1542 
1543  /*----------
1544  * If i >= 0 there can only be overflow if i + j > INT_MAX
1545  * or if j > INT_MAX - i; given i >= 0, INT_MAX - i cannot overflow.
1546  * If i < 0 there can only be overflow if i + j < INT_MIN
1547  * or if j < INT_MIN - i; given i < 0, INT_MIN - i cannot overflow.
1548  *----------
1549  */
1550  if ((i >= 0) ? (j > INT_MAX - i) : (j < INT_MIN - i))
1551  return true;
1552  *ip += j;
1553  return false;
1554 }
int j
Definition: isn.c:74

References i, and j.

Referenced by timesub().

◆ increment_overflow_time()

static bool increment_overflow_time ( pg_time_t tp,
int32  j 
)
static

Definition at line 1557 of file localtime.c.

1558 {
1559  /*----------
1560  * This is like
1561  * 'if (! (TIME_T_MIN <= *tp + j && *tp + j <= TIME_T_MAX)) ...',
1562  * except that it does the right thing even if *tp + j would overflow.
1563  *----------
1564  */
1565  if (!(j < 0
1566  ? (TYPE_SIGNED(pg_time_t) ? TIME_T_MIN - j <= *tp : -1 - j < *tp)
1567  : *tp <= TIME_T_MAX - j))
1568  return true;
1569  *tp += j;
1570  return false;
1571 }
#define TIME_T_MAX
Definition: private.h:73
#define TIME_T_MIN
Definition: private.h:72

References j, TIME_T_MAX, TIME_T_MIN, and TYPE_SIGNED.

Referenced by tzparse().

◆ init_ttinfo()

static void init_ttinfo ( struct ttinfo s,
int32  utoff,
bool  isdst,
int  desigidx 
)
static

Definition at line 108 of file localtime.c.

109 {
110  s->tt_utoff = utoff;
111  s->tt_isdst = isdst;
112  s->tt_desigidx = desigidx;
113  s->tt_ttisstd = false;
114  s->tt_ttisut = false;
115 }
int32 tt_utoff
Definition: pgtz.h:28
bool tt_ttisstd
Definition: pgtz.h:31
int tt_desigidx
Definition: pgtz.h:30
bool tt_isdst
Definition: pgtz.h:29
bool tt_ttisut
Definition: pgtz.h:32
static unsigned char desigidx[TZ_MAX_TYPES]
Definition: zic.c:398

References desigidx, ttinfo::tt_desigidx, ttinfo::tt_isdst, ttinfo::tt_ttisstd, ttinfo::tt_ttisut, and ttinfo::tt_utoff.

Referenced by tzparse().

◆ leapcorr()

static int64 leapcorr ( struct state const *  sp,
pg_time_t  t 
)
static

Definition at line 1574 of file localtime.c.

1575 {
1576  struct lsinfo const *lp;
1577  int i;
1578 
1579  i = sp->leapcnt;
1580  while (--i >= 0)
1581  {
1582  lp = &sp->lsis[i];
1583  if (t >= lp->ls_trans)
1584  return lp->ls_corr;
1585  }
1586  return 0;
1587 }
Definition: pgtz.h:36
pg_time_t ls_trans
Definition: pgtz.h:37
int64 ls_corr
Definition: pgtz.h:38

References i, state::leapcnt, lsinfo::ls_corr, lsinfo::ls_trans, and state::lsis.

Referenced by tzloadbody().

◆ leaps_thru_end_of()

static int leaps_thru_end_of ( const int  y)
static

Definition at line 1406 of file localtime.c.

1407 {
1408  return (y < 0
1409  ? -1 - leaps_thru_end_of_nonneg(-1 - y)
1411 }
int y
Definition: isn.c:72
static int leaps_thru_end_of_nonneg(int y)
Definition: localtime.c:1400

References leaps_thru_end_of_nonneg(), and y.

Referenced by timesub().

◆ leaps_thru_end_of_nonneg()

static int leaps_thru_end_of_nonneg ( int  y)
static

Definition at line 1400 of file localtime.c.

1401 {
1402  return y / 4 - y / 100 + y / 400;
1403 }

References y.

Referenced by leaps_thru_end_of().

◆ localsub()

static struct pg_tm* localsub ( struct state const *  sp,
pg_time_t const *  timep,
struct pg_tm *const  tmp 
)
static

Definition at line 1259 of file localtime.c.

1261 {
1262  const struct ttinfo *ttisp;
1263  int i;
1264  struct pg_tm *result;
1265  const pg_time_t t = *timep;
1266 
1267  if (sp == NULL)
1268  return gmtsub(timep, 0, tmp);
1269  if ((sp->goback && t < sp->ats[0]) ||
1270  (sp->goahead && t > sp->ats[sp->timecnt - 1]))
1271  {
1272  pg_time_t newt = t;
1273  pg_time_t seconds;
1274  pg_time_t years;
1275 
1276  if (t < sp->ats[0])
1277  seconds = sp->ats[0] - t;
1278  else
1279  seconds = t - sp->ats[sp->timecnt - 1];
1280  --seconds;
1281  years = (seconds / SECSPERREPEAT + 1) * YEARSPERREPEAT;
1282  seconds = years * AVGSECSPERYEAR;
1283  if (t < sp->ats[0])
1284  newt += seconds;
1285  else
1286  newt -= seconds;
1287  if (newt < sp->ats[0] ||
1288  newt > sp->ats[sp->timecnt - 1])
1289  return NULL; /* "cannot happen" */
1290  result = localsub(sp, &newt, tmp);
1291  if (result)
1292  {
1293  int64 newy;
1294 
1295  newy = result->tm_year;
1296  if (t < sp->ats[0])
1297  newy -= years;
1298  else
1299  newy += years;
1300  if (!(INT_MIN <= newy && newy <= INT_MAX))
1301  return NULL;
1302  result->tm_year = newy;
1303  }
1304  return result;
1305  }
1306  if (sp->timecnt == 0 || t < sp->ats[0])
1307  {
1308  i = sp->defaulttype;
1309  }
1310  else
1311  {
1312  int lo = 1;
1313  int hi = sp->timecnt;
1314 
1315  while (lo < hi)
1316  {
1317  int mid = (lo + hi) >> 1;
1318 
1319  if (t < sp->ats[mid])
1320  hi = mid;
1321  else
1322  lo = mid + 1;
1323  }
1324  i = (int) sp->types[lo - 1];
1325  }
1326  ttisp = &sp->ttis[i];
1327 
1328  /*
1329  * To get (wrong) behavior that's compatible with System V Release 2.0
1330  * you'd replace the statement below with t += ttisp->tt_utoff;
1331  * timesub(&t, 0L, sp, tmp);
1332  */
1333  result = timesub(&t, ttisp->tt_utoff, sp, tmp);
1334  if (result)
1335  {
1336  result->tm_isdst = ttisp->tt_isdst;
1337  result->tm_zone = unconstify(char *, &sp->chars[ttisp->tt_desigidx]);
1338  }
1339  return result;
1340 }
#define unconstify(underlying_type, expr)
Definition: c.h:1232
static struct pg_tm * gmtsub(pg_time_t const *timep, int32 offset, struct pg_tm *tmp)
Definition: localtime.c:1357
static struct pg_tm * localsub(struct state const *sp, pg_time_t const *timep, struct pg_tm *const tmp)
Definition: localtime.c:1259
#define AVGSECSPERYEAR
Definition: private.h:154
#define YEARSPERREPEAT
Definition: private.h:95
const char * tm_zone
Definition: pgtime.h:46
int tm_isdst
Definition: pgtime.h:44
int tm_year
Definition: pgtime.h:41
Definition: pgtz.h:27

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

Referenced by pg_localtime().

◆ pg_get_timezone_name()

const char* pg_get_timezone_name ( pg_tz tz)

Definition at line 1875 of file localtime.c.

1876 {
1877  if (tz)
1878  return tz->TZname;
1879  return NULL;
1880 }
char TZname[TZ_STRLEN_MAX+1]
Definition: pgtz.h:68

References pg_tz::TZname.

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

◆ pg_get_timezone_offset()

bool pg_get_timezone_offset ( const pg_tz tz,
long int *  gmtoff 
)

Definition at line 1851 of file localtime.c.

1852 {
1853  /*
1854  * The zone could have more than one ttinfo, if it's historically used
1855  * more than one abbreviation. We return true as long as they all have
1856  * the same gmtoff.
1857  */
1858  const struct state *sp;
1859  int i;
1860 
1861  sp = &tz->state;
1862  for (i = 1; i < sp->typecnt; i++)
1863  {
1864  if (sp->ttis[i].tt_utoff != sp->ttis[0].tt_utoff)
1865  return false;
1866  }
1867  *gmtoff = sp->ttis[0].tt_utoff;
1868  return true;
1869 }
struct state state
Definition: pgtz.h:69
struct ttinfo ttis[TZ_MAX_TYPES]
Definition: pgtz.h:51
int typecnt
Definition: pgtz.h:45

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

Referenced by DecodeTimeOnly(), and TimestampTimestampTzRequiresRewrite().

◆ pg_gmtime()

struct pg_tm* pg_gmtime ( const pg_time_t timep)

Definition at line 1389 of file localtime.c.

1390 {
1391  return gmtsub(timep, 0, &tm);
1392 }
static struct pg_tm tm
Definition: localtime.c:104

References gmtsub(), and tm.

Referenced by AddFileToBackupManifest(), and GetEpochTime().

◆ pg_interpret_timezone_abbrev()

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 1757 of file localtime.c.

1762 {
1763  const struct state *sp;
1764  const char *abbrs;
1765  const struct ttinfo *ttisp;
1766  int abbrind;
1767  int cutoff;
1768  int i;
1769  const pg_time_t t = *timep;
1770 
1771  sp = &tz->state;
1772 
1773  /*
1774  * Locate the abbreviation in the zone's abbreviation list. We assume
1775  * there are not duplicates in the list.
1776  */
1777  abbrs = sp->chars;
1778  abbrind = 0;
1779  while (abbrind < sp->charcnt)
1780  {
1781  if (strcmp(abbrev, abbrs + abbrind) == 0)
1782  break;
1783  while (abbrs[abbrind] != '\0')
1784  abbrind++;
1785  abbrind++;
1786  }
1787  if (abbrind >= sp->charcnt)
1788  return false; /* not there! */
1789 
1790  /*
1791  * Unlike pg_next_dst_boundary, we needn't sweat about extrapolation
1792  * (goback/goahead zones). Finding the newest or oldest meaning of the
1793  * abbreviation should get us what we want, since extrapolation would just
1794  * be repeating the newest or oldest meanings.
1795  *
1796  * Use binary search to locate the first transition > cutoff time.
1797  */
1798  {
1799  int lo = 0;
1800  int hi = sp->timecnt;
1801 
1802  while (lo < hi)
1803  {
1804  int mid = (lo + hi) >> 1;
1805 
1806  if (t < sp->ats[mid])
1807  hi = mid;
1808  else
1809  lo = mid + 1;
1810  }
1811  cutoff = lo;
1812  }
1813 
1814  /*
1815  * Scan backwards to find the latest interval using the given abbrev
1816  * before the cutoff time.
1817  */
1818  for (i = cutoff - 1; i >= 0; i--)
1819  {
1820  ttisp = &sp->ttis[sp->types[i]];
1821  if (ttisp->tt_desigidx == abbrind)
1822  {
1823  *gmtoff = ttisp->tt_utoff;
1824  *isdst = ttisp->tt_isdst;
1825  return true;
1826  }
1827  }
1828 
1829  /*
1830  * Not there, so scan forwards to find the first one after.
1831  */
1832  for (i = cutoff; i < sp->timecnt; i++)
1833  {
1834  ttisp = &sp->ttis[sp->types[i]];
1835  if (ttisp->tt_desigidx == abbrind)
1836  {
1837  *gmtoff = ttisp->tt_utoff;
1838  *isdst = ttisp->tt_isdst;
1839  return true;
1840  }
1841  }
1842 
1843  return false; /* hm, not actually used in any interval? */
1844 }
int timecnt
Definition: pgtz.h:44
int charcnt
Definition: pgtz.h:46
unsigned char types[TZ_MAX_TIMES]
Definition: pgtz.h:50
static int charcnt
Definition: zic.c:175

References state::charcnt, charcnt, state::chars, i, pg_tz::state, state::timecnt, ttinfo::tt_desigidx, ttinfo::tt_isdst, ttinfo::tt_utoff, state::ttis, and state::types.

Referenced by DetermineTimeZoneAbbrevOffsetInternal().

◆ pg_localtime()

struct pg_tm* pg_localtime ( const pg_time_t timep,
const pg_tz tz 
)

◆ pg_next_dst_boundary()

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 1610 of file localtime.c.

1617 {
1618  const struct state *sp;
1619  const struct ttinfo *ttisp;
1620  int i;
1621  int j;
1622  const pg_time_t t = *timep;
1623 
1624  sp = &tz->state;
1625  if (sp->timecnt == 0)
1626  {
1627  /* non-DST zone, use lowest-numbered standard type */
1628  i = 0;
1629  while (sp->ttis[i].tt_isdst)
1630  if (++i >= sp->typecnt)
1631  {
1632  i = 0;
1633  break;
1634  }
1635  ttisp = &sp->ttis[i];
1636  *before_gmtoff = ttisp->tt_utoff;
1637  *before_isdst = ttisp->tt_isdst;
1638  return 0;
1639  }
1640  if ((sp->goback && t < sp->ats[0]) ||
1641  (sp->goahead && t > sp->ats[sp->timecnt - 1]))
1642  {
1643  /* For values outside the transition table, extrapolate */
1644  pg_time_t newt = t;
1645  pg_time_t seconds;
1646  pg_time_t tcycles;
1647  int64 icycles;
1648  int result;
1649 
1650  if (t < sp->ats[0])
1651  seconds = sp->ats[0] - t;
1652  else
1653  seconds = t - sp->ats[sp->timecnt - 1];
1654  --seconds;
1655  tcycles = seconds / YEARSPERREPEAT / AVGSECSPERYEAR;
1656  ++tcycles;
1657  icycles = tcycles;
1658  if (tcycles - icycles >= 1 || icycles - tcycles >= 1)
1659  return -1;
1660  seconds = icycles;
1661  seconds *= YEARSPERREPEAT;
1662  seconds *= AVGSECSPERYEAR;
1663  if (t < sp->ats[0])
1664  newt += seconds;
1665  else
1666  newt -= seconds;
1667  if (newt < sp->ats[0] ||
1668  newt > sp->ats[sp->timecnt - 1])
1669  return -1; /* "cannot happen" */
1670 
1671  result = pg_next_dst_boundary(&newt, before_gmtoff,
1672  before_isdst,
1673  boundary,
1674  after_gmtoff,
1675  after_isdst,
1676  tz);
1677  if (t < sp->ats[0])
1678  *boundary -= seconds;
1679  else
1680  *boundary += seconds;
1681  return result;
1682  }
1683 
1684  if (t >= sp->ats[sp->timecnt - 1])
1685  {
1686  /* No known transition > t, so use last known segment's type */
1687  i = sp->types[sp->timecnt - 1];
1688  ttisp = &sp->ttis[i];
1689  *before_gmtoff = ttisp->tt_utoff;
1690  *before_isdst = ttisp->tt_isdst;
1691  return 0;
1692  }
1693  if (t < sp->ats[0])
1694  {
1695  /* For "before", use lowest-numbered standard type */
1696  i = 0;
1697  while (sp->ttis[i].tt_isdst)
1698  if (++i >= sp->typecnt)
1699  {
1700  i = 0;
1701  break;
1702  }
1703  ttisp = &sp->ttis[i];
1704  *before_gmtoff = ttisp->tt_utoff;
1705  *before_isdst = ttisp->tt_isdst;
1706  *boundary = sp->ats[0];
1707  /* And for "after", use the first segment's type */
1708  i = sp->types[0];
1709  ttisp = &sp->ttis[i];
1710  *after_gmtoff = ttisp->tt_utoff;
1711  *after_isdst = ttisp->tt_isdst;
1712  return 1;
1713  }
1714  /* Else search to find the boundary following t */
1715  {
1716  int lo = 1;
1717  int hi = sp->timecnt - 1;
1718 
1719  while (lo < hi)
1720  {
1721  int mid = (lo + hi) >> 1;
1722 
1723  if (t < sp->ats[mid])
1724  hi = mid;
1725  else
1726  lo = mid + 1;
1727  }
1728  i = lo;
1729  }
1730  j = sp->types[i - 1];
1731  ttisp = &sp->ttis[j];
1732  *before_gmtoff = ttisp->tt_utoff;
1733  *before_isdst = ttisp->tt_isdst;
1734  *boundary = sp->ats[i];
1735  j = sp->types[i];
1736  ttisp = &sp->ttis[j];
1737  *after_gmtoff = ttisp->tt_utoff;
1738  *after_isdst = ttisp->tt_isdst;
1739  return 1;
1740 }
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:1610
bool goback
Definition: pgtz.h:47
pg_time_t ats[TZ_MAX_TIMES]
Definition: pgtz.h:49
bool goahead
Definition: pgtz.h:48

References state::ats, AVGSECSPERYEAR, state::goahead, state::goback, i, j, pg_next_dst_boundary(), pg_tz::state, state::timecnt, ttinfo::tt_isdst, ttinfo::tt_utoff, state::ttis, state::typecnt, state::types, and YEARSPERREPEAT.

Referenced by DetermineTimeZoneOffsetInternal(), and pg_next_dst_boundary().

◆ pg_tz_acceptable()

bool pg_tz_acceptable ( pg_tz tz)

Definition at line 1890 of file localtime.c.

1891 {
1892  struct pg_tm *tt;
1893  pg_time_t time2000;
1894 
1895  /*
1896  * To detect leap-second timekeeping, run pg_localtime for what should be
1897  * GMT midnight, 2000-01-01. Insist that the tm_sec value be zero; any
1898  * other result has to be due to leap seconds.
1899  */
1901  tt = pg_localtime(&time2000, tz);
1902  if (!tt || tt->tm_sec != 0)
1903  return false;
1904 
1905  return true;
1906 }
#define UNIX_EPOCH_JDATE
Definition: timestamp.h:234
#define SECS_PER_DAY
Definition: timestamp.h:126
#define POSTGRES_EPOCH_JDATE
Definition: timestamp.h:235
struct pg_tm * pg_localtime(const pg_time_t *timep, const pg_tz *tz)
Definition: localtime.c:1344
int tm_sec
Definition: pgtime.h:36

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

◆ timesub()

static struct pg_tm * timesub ( pg_time_t const *  timep,
int32  offset,
struct state const *  sp,
struct pg_tm tmp 
)
static

Definition at line 1414 of file localtime.c.

1416 {
1417  const struct lsinfo *lp;
1418  pg_time_t tdays;
1419  int idays; /* unsigned would be so 2003 */
1420  int64 rem;
1421  int y;
1422  const int *ip;
1423  int64 corr;
1424  bool hit;
1425  int i;
1426 
1427  corr = 0;
1428  hit = false;
1429  i = (sp == NULL) ? 0 : sp->leapcnt;
1430  while (--i >= 0)
1431  {
1432  lp = &sp->lsis[i];
1433  if (*timep >= lp->ls_trans)
1434  {
1435  corr = lp->ls_corr;
1436  hit = (*timep == lp->ls_trans
1437  && (i == 0 ? 0 : lp[-1].ls_corr) < corr);
1438  break;
1439  }
1440  }
1441  y = EPOCH_YEAR;
1442  tdays = *timep / SECSPERDAY;
1443  rem = *timep % SECSPERDAY;
1444  while (tdays < 0 || tdays >= year_lengths[isleap(y)])
1445  {
1446  int newy;
1447  pg_time_t tdelta;
1448  int idelta;
1449  int leapdays;
1450 
1451  tdelta = tdays / DAYSPERLYEAR;
1452  if (!((!TYPE_SIGNED(pg_time_t) || INT_MIN <= tdelta)
1453  && tdelta <= INT_MAX))
1454  goto out_of_range;
1455  idelta = tdelta;
1456  if (idelta == 0)
1457  idelta = (tdays < 0) ? -1 : 1;
1458  newy = y;
1459  if (increment_overflow(&newy, idelta))
1460  goto out_of_range;
1461  leapdays = leaps_thru_end_of(newy - 1) -
1462  leaps_thru_end_of(y - 1);
1463  tdays -= ((pg_time_t) newy - y) * DAYSPERNYEAR;
1464  tdays -= leapdays;
1465  y = newy;
1466  }
1467 
1468  /*
1469  * Given the range, we can now fearlessly cast...
1470  */
1471  idays = tdays;
1472  rem += offset - corr;
1473  while (rem < 0)
1474  {
1475  rem += SECSPERDAY;
1476  --idays;
1477  }
1478  while (rem >= SECSPERDAY)
1479  {
1480  rem -= SECSPERDAY;
1481  ++idays;
1482  }
1483  while (idays < 0)
1484  {
1485  if (increment_overflow(&y, -1))
1486  goto out_of_range;
1487  idays += year_lengths[isleap(y)];
1488  }
1489  while (idays >= year_lengths[isleap(y)])
1490  {
1491  idays -= year_lengths[isleap(y)];
1492  if (increment_overflow(&y, 1))
1493  goto out_of_range;
1494  }
1495  tmp->tm_year = y;
1497  goto out_of_range;
1498  tmp->tm_yday = idays;
1499 
1500  /*
1501  * The "extra" mods below avoid overflow problems.
1502  */
1503  tmp->tm_wday = EPOCH_WDAY +
1504  ((y - EPOCH_YEAR) % DAYSPERWEEK) *
1506  leaps_thru_end_of(y - 1) -
1508  idays;
1509  tmp->tm_wday %= DAYSPERWEEK;
1510  if (tmp->tm_wday < 0)
1511  tmp->tm_wday += DAYSPERWEEK;
1512  tmp->tm_hour = (int) (rem / SECSPERHOUR);
1513  rem %= SECSPERHOUR;
1514  tmp->tm_min = (int) (rem / SECSPERMIN);
1515 
1516  /*
1517  * A positive leap second requires a special representation. This uses
1518  * "... ??:59:60" et seq.
1519  */
1520  tmp->tm_sec = (int) (rem % SECSPERMIN) + hit;
1521  ip = mon_lengths[isleap(y)];
1522  for (tmp->tm_mon = 0; idays >= ip[tmp->tm_mon]; ++(tmp->tm_mon))
1523  idays -= ip[tmp->tm_mon];
1524  tmp->tm_mday = (int) (idays + 1);
1525  tmp->tm_isdst = 0;
1526  tmp->tm_gmtoff = offset;
1527  return tmp;
1528 
1529 out_of_range:
1530  errno = EOVERFLOW;
1531  return NULL;
1532 }
#define isleap(y)
Definition: datetime.h:271
static int leaps_thru_end_of(const int y)
Definition: localtime.c:1406
static bool increment_overflow(int *ip, int j)
Definition: localtime.c:1539
static const int year_lengths[2]
Definition: localtime.c:631
static const int mon_lengths[2][MONSPERYEAR]
Definition: localtime.c:626
while(p+4<=pend)
#define SECSPERDAY
Definition: private.h:104
#define TM_YEAR_BASE
Definition: private.h:128
#define EPOCH_WDAY
Definition: private.h:131
#define EOVERFLOW
Definition: private.h:41
#define EPOCH_YEAR
Definition: private.h:130
int tm_hour
Definition: pgtime.h:38
int tm_mday
Definition: pgtime.h:39
int tm_mon
Definition: pgtime.h:40
int tm_min
Definition: pgtime.h:37
int tm_yday
Definition: pgtime.h:43
int tm_wday
Definition: pgtime.h:42
long int tm_gmtoff
Definition: pgtime.h:45
static zic_t corr[TZ_MAX_LEAPS]
Definition: zic.c:403

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, mon_lengths, 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, TYPE_SIGNED, while(), y, and year_lengths.

Referenced by gmtsub(), and localsub().

◆ transtime()

static int32 transtime ( const int  year,
const struct rule *const  rulep,
const int32  offset 
)
static

Definition at line 839 of file localtime.c.

841 {
842  bool leapyear;
843  int32 value;
844  int i;
845  int d,
846  m1,
847  yy0,
848  yy1,
849  yy2,
850  dow;
851 
852  INITIALIZE(value);
853  leapyear = isleap(year);
854  switch (rulep->r_type)
855  {
856 
857  case JULIAN_DAY:
858 
859  /*
860  * Jn - Julian day, 1 == January 1, 60 == March 1 even in leap
861  * years. In non-leap years, or if the day number is 59 or less,
862  * just add SECSPERDAY times the day number-1 to the time of
863  * January 1, midnight, to get the day.
864  */
865  value = (rulep->r_day - 1) * SECSPERDAY;
866  if (leapyear && rulep->r_day >= 60)
867  value += SECSPERDAY;
868  break;
869 
870  case DAY_OF_YEAR:
871 
872  /*
873  * n - day of year. Just add SECSPERDAY times the day number to
874  * the time of January 1, midnight, to get the day.
875  */
876  value = rulep->r_day * SECSPERDAY;
877  break;
878 
880 
881  /*
882  * Mm.n.d - nth "dth day" of month m.
883  */
884 
885  /*
886  * Use Zeller's Congruence to get day-of-week of first day of
887  * month.
888  */
889  m1 = (rulep->r_mon + 9) % 12 + 1;
890  yy0 = (rulep->r_mon <= 2) ? (year - 1) : year;
891  yy1 = yy0 / 100;
892  yy2 = yy0 % 100;
893  dow = ((26 * m1 - 2) / 10 +
894  1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7;
895  if (dow < 0)
896  dow += DAYSPERWEEK;
897 
898  /*
899  * "dow" is the day-of-week of the first day of the month. Get the
900  * day-of-month (zero-origin) of the first "dow" day of the month.
901  */
902  d = rulep->r_day - dow;
903  if (d < 0)
904  d += DAYSPERWEEK;
905  for (i = 1; i < rulep->r_week; ++i)
906  {
907  if (d + DAYSPERWEEK >=
908  mon_lengths[(int) leapyear][rulep->r_mon - 1])
909  break;
910  d += DAYSPERWEEK;
911  }
912 
913  /*
914  * "d" is the day-of-month (zero-origin) of the day we want.
915  */
916  value = d * SECSPERDAY;
917  for (i = 0; i < rulep->r_mon - 1; ++i)
918  value += mon_lengths[(int) leapyear][i] * SECSPERDAY;
919  break;
920  }
921 
922  /*
923  * "value" is the year-relative time of 00:00:00 UT on the day in
924  * question. To get the year-relative time of the specified local time on
925  * that day, add the transition time and the current offset from UT.
926  */
927  return value + rulep->r_time + offset;
928 }
static struct @150 value
#define INITIALIZE(x)
Definition: private.h:88

References DAY_OF_YEAR, DAYSPERWEEK, i, INITIALIZE, isleap, JULIAN_DAY, mon_lengths, 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().

◆ typesequiv()

static bool typesequiv ( struct state const *  sp,
int  a,
int  b 
)
static

Definition at line 602 of file localtime.c.

603 {
604  bool result;
605 
606  if (sp == NULL ||
607  a < 0 || a >= sp->typecnt ||
608  b < 0 || b >= sp->typecnt)
609  result = false;
610  else
611  {
612  const struct ttinfo *ap = &sp->ttis[a];
613  const struct ttinfo *bp = &sp->ttis[b];
614 
615  result = (ap->tt_utoff == bp->tt_utoff
616  && ap->tt_isdst == bp->tt_isdst
617  && ap->tt_ttisstd == bp->tt_ttisstd
618  && ap->tt_ttisut == bp->tt_ttisut
619  && (strcmp(&sp->chars[ap->tt_desigidx],
620  &sp->chars[bp->tt_desigidx])
621  == 0));
622  }
623  return result;
624 }
int b
Definition: isn.c:70
int a
Definition: isn.c:69

References a, b, state::chars, ttinfo::tt_desigidx, ttinfo::tt_isdst, ttinfo::tt_ttisstd, ttinfo::tt_ttisut, ttinfo::tt_utoff, state::ttis, and state::typecnt.

Referenced by tzloadbody().

◆ tzload()

int tzload ( const char *  name,
char *  canonname,
struct state sp,
bool  doextend 
)

Definition at line 586 of file localtime.c.

587 {
588  union local_storage *lsp = malloc(sizeof *lsp);
589 
590  if (!lsp)
591  return errno;
592  else
593  {
594  int err = tzloadbody(name, canonname, sp, doextend, lsp);
595 
596  free(lsp);
597  return err;
598  }
599 }
void err(int eval, const char *fmt,...)
Definition: err.c:43
#define free(a)
Definition: header.h:65
static int tzloadbody(char const *name, char *canonname, struct state *sp, bool doextend, union local_storage *lsp)
Definition: localtime.c:211
const char * name

References err(), free, malloc, name, and tzloadbody().

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

◆ tzloadbody()

static int tzloadbody ( char const *  name,
char *  canonname,
struct state sp,
bool  doextend,
union local_storage lsp 
)
static

Definition at line 211 of file localtime.c.

213 {
214  int i;
215  int fid;
216  int stored;
217  ssize_t nread;
218  union input_buffer *up = &lsp->u.u;
219  int tzheadsize = sizeof(struct tzhead);
220 
221  sp->goback = sp->goahead = false;
222 
223  if (!name)
224  {
225  name = TZDEFAULT;
226  if (!name)
227  return EINVAL;
228  }
229 
230  if (name[0] == ':')
231  ++name;
232 
233  fid = pg_open_tzfile(name, canonname);
234  if (fid < 0)
235  return ENOENT; /* pg_open_tzfile may not set errno */
236 
237  nread = read(fid, up->buf, sizeof up->buf);
238  if (nread < tzheadsize)
239  {
240  int err = nread < 0 ? errno : EINVAL;
241 
242  close(fid);
243  return err;
244  }
245  if (close(fid) < 0)
246  return errno;
247  for (stored = 4; stored <= 8; stored *= 2)
248  {
249  int32 ttisstdcnt = detzcode(up->tzhead.tzh_ttisstdcnt);
250  int32 ttisutcnt = detzcode(up->tzhead.tzh_ttisutcnt);
251  int64 prevtr = 0;
252  int32 prevcorr = 0;
257  char const *p = up->buf + tzheadsize;
258 
259  /*
260  * Although tzfile(5) currently requires typecnt to be nonzero,
261  * support future formats that may allow zero typecnt in files that
262  * have a TZ string and no transitions.
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  && (ttisutcnt == typecnt || ttisutcnt == 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  + ttisutcnt)) /* ttisuts */
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  desigidx;
332 
333  ttisp = &sp->ttis[i];
334  ttisp->tt_utoff = detzcode(p);
335  p += 4;
336  isdst = *p++;
337  if (!(isdst < 2))
338  return EINVAL;
339  ttisp->tt_isdst = isdst;
340  desigidx = *p++;
341  if (!(desigidx < sp->charcnt))
342  return EINVAL;
343  ttisp->tt_desigidx = desigidx;
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  /* Leap seconds cannot occur before the Epoch. */
358  if (tr < 0)
359  return EINVAL;
360  if (tr <= TIME_T_MAX)
361  {
362  /*
363  * Leap seconds cannot occur more than once per UTC month, and
364  * UTC months are at least 28 days long (minus 1 second for a
365  * negative leap second). Each leap second's correction must
366  * differ from the previous one's by 1 second.
367  */
368  if (tr - prevtr < 28 * SECSPERDAY - 1
369  || (corr != prevcorr - 1 && corr != prevcorr + 1))
370  return EINVAL;
371  sp->lsis[leapcnt].ls_trans = prevtr = tr;
372  sp->lsis[leapcnt].ls_corr = prevcorr = corr;
373  leapcnt++;
374  }
375  }
376  sp->leapcnt = leapcnt;
377 
378  for (i = 0; i < sp->typecnt; ++i)
379  {
380  struct ttinfo *ttisp;
381 
382  ttisp = &sp->ttis[i];
383  if (ttisstdcnt == 0)
384  ttisp->tt_ttisstd = false;
385  else
386  {
387  if (*p != true && *p != false)
388  return EINVAL;
389  ttisp->tt_ttisstd = *p++;
390  }
391  }
392  for (i = 0; i < sp->typecnt; ++i)
393  {
394  struct ttinfo *ttisp;
395 
396  ttisp = &sp->ttis[i];
397  if (ttisutcnt == 0)
398  ttisp->tt_ttisut = false;
399  else
400  {
401  if (*p != true && *p != false)
402  return EINVAL;
403  ttisp->tt_ttisut = *p++;
404  }
405  }
406 
407  /*
408  * If this is an old file, we're done.
409  */
410  if (up->tzhead.tzh_version[0] == '\0')
411  break;
412  nread -= p - up->buf;
413  memmove(up->buf, p, nread);
414  }
415  if (doextend && nread > 2 &&
416  up->buf[0] == '\n' && up->buf[nread - 1] == '\n' &&
417  sp->typecnt + 2 <= TZ_MAX_TYPES)
418  {
419  struct state *ts = &lsp->u.st;
420 
421  up->buf[nread - 1] = '\0';
422  if (tzparse(&up->buf[1], ts, false))
423  {
424  /*
425  * Attempt to reuse existing abbreviations. Without this,
426  * America/Anchorage would be right on the edge after 2037 when
427  * TZ_MAX_CHARS is 50, as sp->charcnt equals 40 (for LMT AST AWT
428  * APT AHST AHDT YST AKDT AKST) and ts->charcnt equals 10 (for
429  * AKST AKDT). Reusing means sp->charcnt can stay 40 in this
430  * example.
431  */
432  int gotabbr = 0;
433  int charcnt = sp->charcnt;
434 
435  for (i = 0; i < ts->typecnt; i++)
436  {
437  char *tsabbr = ts->chars + ts->ttis[i].tt_desigidx;
438  int j;
439 
440  for (j = 0; j < charcnt; j++)
441  if (strcmp(sp->chars + j, tsabbr) == 0)
442  {
443  ts->ttis[i].tt_desigidx = j;
444  gotabbr++;
445  break;
446  }
447  if (!(j < charcnt))
448  {
449  int tsabbrlen = strlen(tsabbr);
450 
451  if (j + tsabbrlen < TZ_MAX_CHARS)
452  {
453  strcpy(sp->chars + j, tsabbr);
454  charcnt = j + tsabbrlen + 1;
455  ts->ttis[i].tt_desigidx = j;
456  gotabbr++;
457  }
458  }
459  }
460  if (gotabbr == ts->typecnt)
461  {
462  sp->charcnt = charcnt;
463 
464  /*
465  * Ignore any trailing, no-op transitions generated by zic as
466  * they don't help here and can run afoul of bugs in zic 2016j
467  * or earlier.
468  */
469  while (1 < sp->timecnt
470  && (sp->types[sp->timecnt - 1]
471  == sp->types[sp->timecnt - 2]))
472  sp->timecnt--;
473 
474  for (i = 0; i < ts->timecnt; i++)
475  if (sp->timecnt == 0
476  || (sp->ats[sp->timecnt - 1]
477  < ts->ats[i] + leapcorr(sp, ts->ats[i])))
478  break;
479  while (i < ts->timecnt
480  && sp->timecnt < TZ_MAX_TIMES)
481  {
482  sp->ats[sp->timecnt]
483  = ts->ats[i] + leapcorr(sp, ts->ats[i]);
484  sp->types[sp->timecnt] = (sp->typecnt
485  + ts->types[i]);
486  sp->timecnt++;
487  i++;
488  }
489  for (i = 0; i < ts->typecnt; i++)
490  sp->ttis[sp->typecnt++] = ts->ttis[i];
491  }
492  }
493  }
494  if (sp->typecnt == 0)
495  return EINVAL;
496  if (sp->timecnt > 1)
497  {
498  for (i = 1; i < sp->timecnt; ++i)
499  if (typesequiv(sp, sp->types[i], sp->types[0]) &&
500  differ_by_repeat(sp->ats[i], sp->ats[0]))
501  {
502  sp->goback = true;
503  break;
504  }
505  for (i = sp->timecnt - 2; i >= 0; --i)
506  if (typesequiv(sp, sp->types[sp->timecnt - 1],
507  sp->types[i]) &&
508  differ_by_repeat(sp->ats[sp->timecnt - 1],
509  sp->ats[i]))
510  {
511  sp->goahead = true;
512  break;
513  }
514  }
515 
516  /*
517  * Infer sp->defaulttype from the data. Although this default type is
518  * always zero for data from recent tzdb releases, things are trickier for
519  * data from tzdb 2018e or earlier.
520  *
521  * The first set of heuristics work around bugs in 32-bit data generated
522  * by tzdb 2013c or earlier. The workaround is for zones like
523  * Australia/Macquarie where timestamps before the first transition have a
524  * time type that is not the earliest standard-time type. See:
525  * https://mm.icann.org/pipermail/tz/2013-May/019368.html
526  */
527 
528  /*
529  * If type 0 is unused in transitions, it's the type to use for early
530  * times.
531  */
532  for (i = 0; i < sp->timecnt; ++i)
533  if (sp->types[i] == 0)
534  break;
535  i = i < sp->timecnt ? -1 : 0;
536 
537  /*
538  * Absent the above, if there are transition times and the first
539  * transition is to a daylight time find the standard type less than and
540  * closest to the type of the first transition.
541  */
542  if (i < 0 && sp->timecnt > 0 && sp->ttis[sp->types[0]].tt_isdst)
543  {
544  i = sp->types[0];
545  while (--i >= 0)
546  if (!sp->ttis[i].tt_isdst)
547  break;
548  }
549 
550  /*
551  * The next heuristics are for data generated by tzdb 2018e or earlier,
552  * for zones like EST5EDT where the first transition is to DST.
553  */
554 
555  /*
556  * If no result yet, find the first standard type. If there is none, punt
557  * to type zero.
558  */
559  if (i < 0)
560  {
561  i = 0;
562  while (sp->ttis[i].tt_isdst)
563  if (++i >= sp->typecnt)
564  {
565  i = 0;
566  break;
567  }
568  }
569 
570  /*
571  * A simple 'sp->defaulttype = 0;' would suffice here if we didn't have to
572  * worry about 2018e-or-earlier data. Even simpler would be to remove the
573  * defaulttype member and just use 0 in its place.
574  */
575  sp->defaulttype = i;
576 
577  return 0;
578 }
int pg_open_tzfile(const char *name, char *canonname)
Definition: findtimezone.c:65
#define close(a)
Definition: win32.h:12
#define read(a, b, c)
Definition: win32.h:13
static int64 leapcorr(struct state const *sp, pg_time_t t)
Definition: localtime.c:1574
static int32 detzcode(const char *const codep)
Definition: localtime.c:118
static bool differ_by_repeat(const pg_time_t t1, const pg_time_t t0)
Definition: localtime.c:170
static int64 detzcode64(const char *const codep)
Definition: localtime.c:144
static bool typesequiv(struct state const *sp, int a, int b)
Definition: localtime.c:602
union input_buffer u
Definition: localtime.c:195
int leapcnt
Definition: pgtz.h:43
struct lsinfo lsis[TZ_MAX_LEAPS]
Definition: pgtz.h:54
int defaulttype
Definition: pgtz.h:61
Definition: tzfile.h:40
char tzh_timecnt[4]
Definition: tzfile.h:47
char tzh_ttisstdcnt[4]
Definition: tzfile.h:45
char tzh_version[1]
Definition: tzfile.h:42
char tzh_charcnt[4]
Definition: tzfile.h:49
char tzh_leapcnt[4]
Definition: tzfile.h:46
char tzh_ttisutcnt[4]
Definition: tzfile.h:44
char tzh_typecnt[4]
Definition: tzfile.h:48
#define TZ_MAX_CHARS
Definition: tzfile.h:105
#define TZ_MAX_TYPES
Definition: tzfile.h:103
#define TZ_MAX_TIMES
Definition: tzfile.h:100
#define TZ_MAX_LEAPS
Definition: tzfile.h:108
#define TZDEFAULT
Definition: tzfile.h:27
char buf[2 *sizeof(struct tzhead)+2 *sizeof(struct state)+4 *TZ_MAX_TIMES]
Definition: localtime.c:185
struct tzhead tzhead
Definition: localtime.c:181
struct local_storage::file_analysis u
static int typecnt
Definition: zic.c:196
static ptrdiff_t timecnt
Definition: zic.c:194
static int leapcnt
Definition: zic.c:179

References state::ats, input_buffer::buf, state::charcnt, charcnt, state::chars, close, corr, state::defaulttype, desigidx, detzcode(), detzcode64(), differ_by_repeat(), err(), state::goahead, state::goback, i, j, state::leapcnt, leapcnt, leapcorr(), lsinfo::ls_corr, lsinfo::ls_trans, state::lsis, name, pg_open_tzfile(), read, SECSPERDAY, local_storage::file_analysis::st, TIME_T_MAX, TIME_T_MIN, state::timecnt, timecnt, ttinfo::tt_desigidx, ttinfo::tt_isdst, ttinfo::tt_ttisstd, ttinfo::tt_ttisut, ttinfo::tt_utoff, 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_ttisstdcnt, tzhead::tzh_ttisutcnt, tzhead::tzh_typecnt, tzhead::tzh_version, input_buffer::tzhead, tzparse(), local_storage::file_analysis::u, and local_storage::u.

Referenced by tzload().

◆ tzparse()

bool tzparse ( const char *  name,
struct state sp,
bool  lastditch 
)

Definition at line 936 of file localtime.c.

937 {
938  const char *stdname;
939  const char *dstname = NULL;
940  size_t stdlen;
941  size_t dstlen;
942  size_t charcnt;
943  int32 stdoffset;
944  int32 dstoffset;
945  char *cp;
946  bool load_ok;
947 
948  stdname = name;
949  if (lastditch)
950  {
951  /* Unlike IANA, don't assume name is exactly "GMT" */
952  stdlen = strlen(name); /* length of standard zone name */
953  name += stdlen;
954  stdoffset = 0;
955  }
956  else
957  {
958  if (*name == '<')
959  {
960  name++;
961  stdname = name;
962  name = getqzname(name, '>');
963  if (*name != '>')
964  return false;
965  stdlen = name - stdname;
966  name++;
967  }
968  else
969  {
970  name = getzname(name);
971  stdlen = name - stdname;
972  }
973  if (*name == '\0') /* we allow empty STD abbrev, unlike IANA */
974  return false;
975  name = getoffset(name, &stdoffset);
976  if (name == NULL)
977  return false;
978  }
979  charcnt = stdlen + 1;
980  if (sizeof sp->chars < charcnt)
981  return false;
982 
983  /*
984  * The IANA code always tries to tzload(TZDEFRULES) here. We do not want
985  * to do that; it would be bad news in the lastditch case, where we can't
986  * assume pg_open_tzfile() is sane yet. Moreover, if we did load it and
987  * it contains leap-second-dependent info, that would cause problems too.
988  * Finally, IANA has deprecated the TZDEFRULES feature, so it presumably
989  * will die at some point. Desupporting it now seems like good
990  * future-proofing.
991  */
992  load_ok = false;
993  sp->goback = sp->goahead = false; /* simulate failed tzload() */
994  sp->leapcnt = 0; /* intentionally assume no leap seconds */
995 
996  if (*name != '\0')
997  {
998  if (*name == '<')
999  {
1000  dstname = ++name;
1001  name = getqzname(name, '>');
1002  if (*name != '>')
1003  return false;
1004  dstlen = name - dstname;
1005  name++;
1006  }
1007  else
1008  {
1009  dstname = name;
1010  name = getzname(name);
1011  dstlen = name - dstname; /* length of DST abbr. */
1012  }
1013  if (!dstlen)
1014  return false;
1015  charcnt += dstlen + 1;
1016  if (sizeof sp->chars < charcnt)
1017  return false;
1018  if (*name != '\0' && *name != ',' && *name != ';')
1019  {
1020  name = getoffset(name, &dstoffset);
1021  if (name == NULL)
1022  return false;
1023  }
1024  else
1025  dstoffset = stdoffset - SECSPERHOUR;
1026  if (*name == '\0' && !load_ok)
1028  if (*name == ',' || *name == ';')
1029  {
1030  struct rule start;
1031  struct rule end;
1032  int year;
1033  int yearlim;
1034  int timecnt;
1035  pg_time_t janfirst;
1036  int32 janoffset = 0;
1037  int yearbeg;
1038 
1039  ++name;
1040  if ((name = getrule(name, &start)) == NULL)
1041  return false;
1042  if (*name++ != ',')
1043  return false;
1044  if ((name = getrule(name, &end)) == NULL)
1045  return false;
1046  if (*name != '\0')
1047  return false;
1048  sp->typecnt = 2; /* standard time and DST */
1049 
1050  /*
1051  * Two transitions per year, from EPOCH_YEAR forward.
1052  */
1053  init_ttinfo(&sp->ttis[0], -stdoffset, false, 0);
1054  init_ttinfo(&sp->ttis[1], -dstoffset, true, stdlen + 1);
1055  sp->defaulttype = 0;
1056  timecnt = 0;
1057  janfirst = 0;
1058  yearbeg = EPOCH_YEAR;
1059 
1060  do
1061  {
1062  int32 yearsecs
1063  = year_lengths[isleap(yearbeg - 1)] * SECSPERDAY;
1064 
1065  yearbeg--;
1066  if (increment_overflow_time(&janfirst, -yearsecs))
1067  {
1068  janoffset = -yearsecs;
1069  break;
1070  }
1071  } while (EPOCH_YEAR - YEARSPERREPEAT / 2 < yearbeg);
1072 
1073  yearlim = yearbeg + YEARSPERREPEAT + 1;
1074  for (year = yearbeg; year < yearlim; year++)
1075  {
1076  int32
1077  starttime = transtime(year, &start, stdoffset),
1078  endtime = transtime(year, &end, dstoffset);
1079  int32
1080  yearsecs = (year_lengths[isleap(year)]
1081  * SECSPERDAY);
1082  bool reversed = endtime < starttime;
1083 
1084  if (reversed)
1085  {
1086  int32 swap = starttime;
1087 
1088  starttime = endtime;
1089  endtime = swap;
1090  }
1091  if (reversed
1092  || (starttime < endtime
1093  && (endtime - starttime
1094  < (yearsecs
1095  + (stdoffset - dstoffset)))))
1096  {
1097  if (TZ_MAX_TIMES - 2 < timecnt)
1098  break;
1099  sp->ats[timecnt] = janfirst;
1101  (&sp->ats[timecnt],
1102  janoffset + starttime))
1103  sp->types[timecnt++] = !reversed;
1104  sp->ats[timecnt] = janfirst;
1106  (&sp->ats[timecnt],
1107  janoffset + endtime))
1108  {
1109  sp->types[timecnt++] = reversed;
1110  yearlim = year + YEARSPERREPEAT + 1;
1111  }
1112  }
1114  (&janfirst, janoffset + yearsecs))
1115  break;
1116  janoffset = 0;
1117  }
1118  sp->timecnt = timecnt;
1119  if (!timecnt)
1120  {
1121  sp->ttis[0] = sp->ttis[1];
1122  sp->typecnt = 1; /* Perpetual DST. */
1123  }
1124  else if (YEARSPERREPEAT < year - yearbeg)
1125  sp->goback = sp->goahead = true;
1126  }
1127  else
1128  {
1129  int32 theirstdoffset;
1130  int32 theirdstoffset;
1131  int32 theiroffset;
1132  bool isdst;
1133  int i;
1134  int j;
1135 
1136  if (*name != '\0')
1137  return false;
1138 
1139  /*
1140  * Initial values of theirstdoffset and theirdstoffset.
1141  */
1142  theirstdoffset = 0;
1143  for (i = 0; i < sp->timecnt; ++i)
1144  {
1145  j = sp->types[i];
1146  if (!sp->ttis[j].tt_isdst)
1147  {
1148  theirstdoffset =
1149  -sp->ttis[j].tt_utoff;
1150  break;
1151  }
1152  }
1153  theirdstoffset = 0;
1154  for (i = 0; i < sp->timecnt; ++i)
1155  {
1156  j = sp->types[i];
1157  if (sp->ttis[j].tt_isdst)
1158  {
1159  theirdstoffset =
1160  -sp->ttis[j].tt_utoff;
1161  break;
1162  }
1163  }
1164 
1165  /*
1166  * Initially we're assumed to be in standard time.
1167  */
1168  isdst = false;
1169  theiroffset = theirstdoffset;
1170 
1171  /*
1172  * Now juggle transition times and types tracking offsets as you
1173  * do.
1174  */
1175  for (i = 0; i < sp->timecnt; ++i)
1176  {
1177  j = sp->types[i];
1178  sp->types[i] = sp->ttis[j].tt_isdst;
1179  if (sp->ttis[j].tt_ttisut)
1180  {
1181  /* No adjustment to transition time */
1182  }
1183  else
1184  {
1185  /*
1186  * If daylight saving time is in effect, and the
1187  * transition time was not specified as standard time, add
1188  * the daylight saving time offset to the transition time;
1189  * otherwise, add the standard time offset to the
1190  * transition time.
1191  */
1192  /*
1193  * Transitions from DST to DDST will effectively disappear
1194  * since POSIX provides for only one DST offset.
1195  */
1196  if (isdst && !sp->ttis[j].tt_ttisstd)
1197  {
1198  sp->ats[i] += dstoffset -
1199  theirdstoffset;
1200  }
1201  else
1202  {
1203  sp->ats[i] += stdoffset -
1204  theirstdoffset;
1205  }
1206  }
1207  theiroffset = -sp->ttis[j].tt_utoff;
1208  if (sp->ttis[j].tt_isdst)
1209  theirdstoffset = theiroffset;
1210  else
1211  theirstdoffset = theiroffset;
1212  }
1213 
1214  /*
1215  * Finally, fill in ttis.
1216  */
1217  init_ttinfo(&sp->ttis[0], -stdoffset, false, 0);
1218  init_ttinfo(&sp->ttis[1], -dstoffset, true, stdlen + 1);
1219  sp->typecnt = 2;
1220  sp->defaulttype = 0;
1221  }
1222  }
1223  else
1224  {
1225  dstlen = 0;
1226  sp->typecnt = 1; /* only standard time */
1227  sp->timecnt = 0;
1228  init_ttinfo(&sp->ttis[0], -stdoffset, false, 0);
1229  sp->defaulttype = 0;
1230  }
1231  sp->charcnt = charcnt;
1232  cp = sp->chars;
1233  memcpy(cp, stdname, stdlen);
1234  cp += stdlen;
1235  *cp++ = '\0';
1236  if (dstlen != 0)
1237  {
1238  memcpy(cp, dstname, dstlen);
1239  *(cp + dstlen) = '\0';
1240  }
1241  return true;
1242 }
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:77
static const char * getrule(const char *strp, struct rule *const rulep)
Definition: localtime.c:778
static int32 transtime(const int year, const struct rule *const rulep, const int32 offset)
Definition: localtime.c:839
#define TZDEFRULESTRING
Definition: localtime.c:61
static const char * getzname(const char *strp)
Definition: localtime.c:642
static bool increment_overflow_time(pg_time_t *tp, int32 j)
Definition: localtime.c:1557
static void init_ttinfo(struct ttinfo *s, int32 utoff, bool isdst, int desigidx)
Definition: localtime.c:108
static const char * getqzname(const char *strp, const int delim)
Definition: localtime.c:663
Definition: localtime.c:73

References state::ats, state::charcnt, charcnt, state::chars, state::defaulttype, EPOCH_YEAR, getoffset(), getqzname(), getrule(), getzname(), state::goahead, state::goback, i, if(), increment_overflow_time(), init_ttinfo(), isleap, j, state::leapcnt, name, SECSPERDAY, SECSPERHOUR, state::timecnt, timecnt, transtime(), ttinfo::tt_isdst, ttinfo::tt_ttisstd, ttinfo::tt_ttisut, ttinfo::tt_utoff, state::ttis, state::typecnt, state::types, TZ_MAX_TIMES, TZDEFRULESTRING, year_lengths, and YEARSPERREPEAT.

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

Variable Documentation

◆ gmt

const char gmt[] = "GMT"
static

Definition at line 53 of file localtime.c.

Referenced by gbt_tstz_compress(), and gmtload().

◆ mon_lengths

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 626 of file localtime.c.

Referenced by timesub(), and transtime().

◆ tm

struct pg_tm tm
static

Definition at line 93 of file localtime.c.

Referenced by abstime2tm(), AdjustFractDays(), AdjustFractSeconds(), AppendTimestampSeconds(), build_time_t(), cache_locale_time(), check_recovery_target_time(), ClearPgTm(), createBackupLabel(), date2timestamptz_opt_overflow(), date_in(), date_out(), DCH_to_char(), DecodeDate(), DecodeDateTime(), DecodeInterval(), DecodeISO8601Interval(), DecodeNumber(), DecodeNumberField(), DecodeTime(), DecodeTimeOnly(), DetermineTimeZoneAbbrevOffset(), DetermineTimeZoneAbbrevOffsetTS(), DetermineTimeZoneOffset(), DetermineTimeZoneOffsetInternal(), do_to_timestamp(), dttofmtasc_replace(), EncodeDateOnly(), EncodeDateTime(), EncodeInterval(), EncodeTimeOnly(), gbt_num_compress(), get_timezone_offset(), GetCurrentDateTime(), GetCurrentTimeUsec(), GetEpochTime(), GetSQLCurrentDate(), GetSQLCurrentTime(), GetSQLLocalTime(), identify_system_timezone(), interval2tm(), interval_part_common(), interval_to_char(), interval_trunc(), JsonEncodeDateTime(), locale_date_order(), make_date(), make_timestamp_internal(), map_sql_value_to_xml_value(), my_strftime(), parse_datetime(), parse_sane_timezone(), 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(), score_timezone(), set_next_rotation_time(), SetEpochTimestamp(), tarOpen(), time2tm(), time_in(), time_out(), time_part_common(), time_t_to_timestamptz(), time_timetz(), timestamp2timestamptz_opt_overflow(), timestamp2tm(), timestamp_age(), timestamp_date(), timestamp_in(), timestamp_out(), timestamp_part_common(), timestamp_pl_interval(), timestamp_recv(), timestamp_time(), timestamp_to_char(), timestamp_trunc(), timestamp_zone(), timestamptz2timestamp(), timestamptz_age(), timestamptz_date(), timestamptz_in(), timestamptz_out(), timestamptz_part_common(), timestamptz_pl_interval_internal(), timestamptz_recv(), timestamptz_time(), timestamptz_timetz(), timestamptz_to_char(), timestamptz_to_str(), timestamptz_trunc_internal(), timestamptz_zone(), timetz2tm(), timetz_in(), timetz_out(), timetz_part_common(), timetz_zone(), tm2interval(), tm2time(), tm2timestamp(), tm2timetz(), to_date(), to_timestamp(), typenameTypeMod(), ValidateDate(), WriteHead(), and writezone().

◆ wildabbr

const char wildabbr[] = WILDABBR
static

Definition at line 51 of file localtime.c.

Referenced by gmtsub().

◆ year_lengths

const int year_lengths[2]
static
Initial value:

Definition at line 631 of file localtime.c.

Referenced by timesub(), and tzparse().