PostgreSQL Source Code git master
Loading...
Searching...
No Matches
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 UNCONST(a)   unconstify(char *, a)
 
#define WILDABBR   " "
 
#define TZDEFRULESTRING   ",M3.2.0,M11.1.0"
 
#define WRONG   (-1)
 

Enumerations

enum  r_type { JULIAN_DAY , DAY_OF_YEAR , MONTH_NTH_DAY_OF_WEEK }
 
enum  { TZLOAD_FROMENV = 1 }
 
enum  { TZLOAD_TZSTRING = 2 }
 
enum  { TZLOAD_TZDIR_SUB = 4 }
 

Functions

static int leapcount (ATTRIBUTE_MAYBE_UNUSED struct state const *sp)
 
static void set_leapcount (ATTRIBUTE_MAYBE_UNUSED struct state *sp, ATTRIBUTE_MAYBE_UNUSED int leapcnt)
 
static struct lsinfo lsinfo (ATTRIBUTE_MAYBE_UNUSED struct state const *sp, ATTRIBUTE_MAYBE_UNUSED int i)
 
static void set_lsinfo (ATTRIBUTE_MAYBE_UNUSED struct state *sp, ATTRIBUTE_MAYBE_UNUSED int i, ATTRIBUTE_MAYBE_UNUSED struct lsinfo lsinfo)
 
static struct pg_tmgmtsub (pg_time_t const *timep, int_fast32_t offset, struct pg_tm *tmp)
 
static bool increment_overflow (int *ip, int j)
 
static bool increment_overflow_time (pg_time_t *tp, int_fast32_2s j)
 
static int_fast32_2s leapcorr (struct state const *sp, pg_time_t t)
 
static struct pg_tmtimesub (pg_time_t const *timep, int_fast32_t offset, struct state const *sp, struct pg_tm *tmp)
 
static bool tzparse (const char *name, struct state *sp, struct state const *basep)
 
static void init_ttinfo (struct ttinfo *s, int_fast32_t utoff, bool isdst, desigidx_type desigidx)
 
static int_fast32_2s detzcode (const char *const codep)
 
static int_fast64_t detzcode64 (const char *const codep)
 
static int tzloadbody (char const *name, char *canonname, struct state *sp, char tzloadflags, union local_storage **lspp)
 
static int tzload (char const *name, char *canonname, struct state *sp, char tzloadflags)
 
static bool is_digit (char c)
 
static ATTRIBUTE_PURE_114833 const chargetzname (const char *strp)
 
static ATTRIBUTE_PURE_114833 const chargetqzname (const char *strp, const int delim)
 
static const chargetnum (const char *strp, int *const nump, const int min, const int max)
 
static const chargetsecs (const char *strp, int_fast32_t *const secsp)
 
static const chargetoffset (const char *strp, int_fast32_t *const offsetp)
 
static const chargetrule (const char *strp, struct rule *const rulep)
 
static int_fast32_t transtime (const int year, const struct rule *const rulep, const int_fast32_t offset)
 
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 pg_time_t leaps_thru_end_of_nonneg (pg_time_t y)
 
static pg_time_t leaps_thru_end_of (pg_time_t y)
 
bool pg_tzload (const char *name, char *canonname, struct state *sp)
 
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_timezone_abbrev_is_known (const char *abbrev, bool *isfixed, long int *gmtoff, int *isdst, const pg_tz *tz)
 
const charpg_get_next_timezone_abbrev (int *indx, const pg_tz *tz)
 
bool pg_get_timezone_offset (const pg_tz *tz, long int *gmtoff)
 
const charpg_get_timezone_name (pg_tz *tz)
 
bool pg_tz_acceptable (pg_tz *tz)
 

Variables

static const char wildabbr [] = WILDABBR
 
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 67 of file localtime.c.

◆ UNCONST

#define UNCONST (   a)    unconstify(char *, a)

Definition at line 33 of file localtime.c.

◆ WILDABBR

#define WILDABBR   " "

Definition at line 55 of file localtime.c.

◆ WRONG

#define WRONG   (-1)

Definition at line 1503 of file localtime.c.

Enumeration Type Documentation

◆ anonymous enum

Enumerator
TZLOAD_FROMENV 

Definition at line 243 of file localtime.c.

244{
245TZLOAD_FROMENV = 1}; /* The TZ string came from the environment. */
@ TZLOAD_FROMENV
Definition localtime.c:245

◆ anonymous enum

Enumerator
TZLOAD_TZSTRING 

Definition at line 246 of file localtime.c.

247{
248TZLOAD_TZSTRING = 2}; /* Read any newline-surrounded TZ string. */
@ TZLOAD_TZSTRING
Definition localtime.c:248

◆ anonymous enum

Enumerator
TZLOAD_TZDIR_SUB 

Definition at line 249 of file localtime.c.

250{
251TZLOAD_TZDIR_SUB = 4}; /* TZ should be a file under TZDIR. */
@ TZLOAD_TZDIR_SUB
Definition localtime.c:251

◆ r_type

Enumerator
JULIAN_DAY 
DAY_OF_YEAR 
MONTH_NTH_DAY_OF_WEEK 

Definition at line 109 of file localtime.c.

110{
111 JULIAN_DAY, /* Jn = Julian day */
112 DAY_OF_YEAR, /* n = day of year */
113 MONTH_NTH_DAY_OF_WEEK /* Mm.n.d = month, week, day of week */
114};
@ JULIAN_DAY
Definition localtime.c:111
@ MONTH_NTH_DAY_OF_WEEK
Definition localtime.c:113
@ DAY_OF_YEAR
Definition localtime.c:112

Function Documentation

◆ detzcode()

static int_fast32_2s detzcode ( const char *const  codep)
static

Definition at line 163 of file localtime.c.

164{
165 int i;
167 maxval = TWO_31_MINUS_1,
168 minval = -1 - maxval,
169 result;
170
171 result = codep[0] & 0x7f;
172 for (i = 1; i < 4; ++i)
173 result = (result << 8) | (codep[i] & 0xff);
174
175 if (codep[0] & 0x80)
176 {
177 /*
178 * Do two's-complement negation even on non-two's-complement machines.
179 * This cannot overflow, as int_fast32_2s is wide enough.
180 */
181 result += minval;
182 }
183 return result;
184}
uint32 result
int i
Definition isn.c:77
int_fast32_t int_fast32_2s
Definition pgtz.h:45
static int fb(int x)
#define TWO_31_MINUS_1
Definition private.h:205

References fb(), i, result, and TWO_31_MINUS_1.

Referenced by tzloadbody().

◆ detzcode64()

static int_fast64_t detzcode64 ( const char *const  codep)
static

Definition at line 187 of file localtime.c.

188{
190 int i;
191 int_fast64_t one = 1;
192 int_fast64_t halfmaxval = one << (64 - 2);
193 int_fast64_t maxval = halfmaxval - 1 + halfmaxval;
194 int_fast64_t minval = -TWOS_COMPLEMENT(int_fast64_t) - maxval;
195
196 result = codep[0] & 0x7f;
197 for (i = 1; i < 8; ++i)
198 result = (result << 8) | (codep[i] & 0xff);
199
200 if (codep[0] & 0x80)
201 {
202 /*
203 * Do two's-complement negation even on non-two's-complement machines.
204 * If the result would be minval - 1, return minval.
205 */
207 result += minval;
208 }
209 return result;
210}
#define TWOS_COMPLEMENT(type)
Definition private.h:146

References fb(), i, result, and TWOS_COMPLEMENT.

Referenced by tzloadbody().

◆ getnum()

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

Definition at line 689 of file localtime.c.

690{
691 char c;
692 int num;
693
694 if (strp == NULL || !is_digit(c = *strp))
695 return NULL;
696 num = 0;
697 do
698 {
699 num = num * 10 + (c - '0');
700 if (num > max)
701 return NULL; /* illegal value */
702 c = *++strp;
703 } while (is_digit(c));
704 if (num < min)
705 return NULL; /* illegal value */
706 *nump = num;
707 return strp;
708}
static bool is_digit(char c)
Definition localtime.c:639
char * c
#define min(a, b)
Definition private.h:155
#define max(a, b)
Definition private.h:154

References fb(), is_digit(), max, and min.

Referenced by getrule(), and getsecs().

◆ getoffset()

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

Definition at line 761 of file localtime.c.

762{
763 bool neg = false;
764
765 if (*strp == '-')
766 {
767 neg = true;
768 ++strp;
769 }
770 else if (*strp == '+')
771 ++strp;
773 if (strp == NULL)
774 return NULL; /* illegal time */
775 if (neg)
776 *offsetp = -*offsetp;
777 return strp;
778}
static const char * getsecs(const char *strp, int_fast32_t *const secsp)
Definition localtime.c:719

References fb(), and getsecs().

Referenced by getrule(), and tzparse().

◆ getqzname()

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

Definition at line 672 of file localtime.c.

673{
674 int c;
675
676 while ((c = *strp) != '\0' && c != delim)
677 ++strp;
678 return strp;
679}

References fb().

Referenced by tzparse().

◆ getrule()

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

Definition at line 789 of file localtime.c.

790{
791 if (*strp == 'J')
792 {
793 /*
794 * Julian day.
795 */
796 rulep->r_type = JULIAN_DAY;
797 ++strp;
798 strp = getnum(strp, &rulep->r_day, 1, DAYSPERNYEAR);
799 }
800 else if (*strp == 'M')
801 {
802 /*
803 * Month, week, day.
804 */
806 ++strp;
807 strp = getnum(strp, &rulep->r_mon, 1, MONSPERYEAR);
808 if (strp == NULL)
809 return NULL;
810 if (*strp++ != '.')
811 return NULL;
812 strp = getnum(strp, &rulep->r_week, 1, 5);
813 if (strp == NULL)
814 return NULL;
815 if (*strp++ != '.')
816 return NULL;
817 strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1);
818 }
819 else if (is_digit(*strp))
820 {
821 /*
822 * Day of year.
823 */
824 rulep->r_type = DAY_OF_YEAR;
825 strp = getnum(strp, &rulep->r_day, 0, DAYSPERLYEAR - 1);
826 }
827 else
828 return NULL; /* invalid format */
829 if (strp == NULL)
830 return NULL;
831 if (*strp == '/')
832 {
833 /*
834 * Time specified.
835 */
836 ++strp;
837 strp = getoffset(strp, &rulep->r_time);
838 }
839 else
840 rulep->r_time = 2 * SECSPERHOUR; /* default = 2:00:00 */
841 return strp;
842}
static const char * getnum(const char *strp, int *const nump, const int min, const int max)
Definition localtime.c:689
static const char * getoffset(const char *strp, int_fast32_t *const offsetp)
Definition localtime.c:761
@ DAYSPERNYEAR
Definition private.h:214
@ DAYSPERLYEAR
Definition private.h:215
@ DAYSPERWEEK
Definition private.h:213
@ MONSPERYEAR
Definition private.h:216
@ SECSPERHOUR
Definition private.h:211

References DAY_OF_YEAR, DAYSPERLYEAR, DAYSPERNYEAR, DAYSPERWEEK, fb(), getnum(), getoffset(), is_digit(), JULIAN_DAY, MONSPERYEAR, MONTH_NTH_DAY_OF_WEEK, and SECSPERHOUR.

Referenced by tzparse().

◆ getsecs()

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

Definition at line 719 of file localtime.c.

720{
721 int num;
723
724 /*
725 * 'HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-POSIX rules like
726 * "M10.4.6/26", which does not conform to POSIX, but which specifies the
727 * equivalent of "02:00 on the first Sunday on or after 23 Oct".
728 */
729 strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1);
730 if (strp == NULL)
731 return NULL;
732 *secsp = num * secsperhour;
733 if (*strp == ':')
734 {
735 ++strp;
736 strp = getnum(strp, &num, 0, MINSPERHOUR - 1);
737 if (strp == NULL)
738 return NULL;
739 *secsp += num * SECSPERMIN;
740 if (*strp == ':')
741 {
742 ++strp;
743 /* 'SECSPERMIN' allows for leap seconds. */
744 strp = getnum(strp, &num, 0, SECSPERMIN);
745 if (strp == NULL)
746 return NULL;
747 *secsp += num;
748 }
749 }
750 return strp;
751}
@ SECSPERMIN
Definition private.h:209
@ MINSPERHOUR
Definition private.h:210
@ HOURSPERDAY
Definition private.h:212

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

Referenced by getoffset().

◆ getzname()

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

Definition at line 651 of file localtime.c.

652{
653 char c;
654
655 while ((c = *strp) != '\0' && !is_digit(c) && c != ',' && c != '-' &&
656 c != '+')
657 ++strp;
658 return strp;
659}

References fb(), and is_digit().

Referenced by tzparse().

◆ gmtload()

static void gmtload ( struct state *const  sp)
static

Definition at line 1172 of file localtime.c.

1173{
1174 /* PG: for historical compatibility, use "GMT" not "UTC" as TZ abbrev */
1175 tzparse("GMT0", sp, NULL);
1176}
static bool tzparse(const char *name, struct state *sp, struct state const *basep)
Definition localtime.c:949

References fb(), and tzparse().

Referenced by gmtsub(), and pg_tzload().

◆ gmtsub()

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

Definition at line 1302 of file localtime.c.

1304{
1305 struct pg_tm *result;
1306
1307 /* GMT timezone state data is kept here */
1308 static struct state *gmtptr = NULL;
1309
1310 if (gmtptr == NULL)
1311 {
1312 /* Allocate on first use */
1313 gmtptr = (struct state *) malloc(sizeof(struct state));
1314 if (gmtptr == NULL)
1315 return NULL; /* errno should be set by malloc */
1316 gmtload(gmtptr);
1317 }
1318
1319 result = timesub(timep, offset, gmtptr, tmp);
1320#ifdef TM_ZONE
1321
1322 /*
1323 * Could get fancy here and deliver something such as "+xx" or "-xx" if
1324 * offset is non-zero, but this is no time for a treasure hunt.
1325 */
1326 tmp->TM_ZONE = UNCONST(offset ? wildabbr
1327 : gmtptr->chars);
1328#endif /* defined TM_ZONE */
1329 return result;
1330}
static void gmtload(struct state *const sp)
Definition localtime.c:1172
#define UNCONST(a)
Definition localtime.c:33
static struct pg_tm * timesub(pg_time_t const *timep, int_fast32_t offset, struct state const *sp, struct pg_tm *tmp)
Definition localtime.c:1358
static const char wildabbr[]
Definition localtime.c:58
#define malloc(a)
Definition pgtime.h:35
struct state * tmp
Definition regguts.h:339
static char chars[TZ_MAX_CHARS]
Definition zic.c:485

References fb(), gmtload(), malloc, result, timesub(), state::tmp, UNCONST, and wildabbr.

Referenced by localsub(), and pg_gmtime().

◆ increment_overflow()

static bool increment_overflow ( int ip,
int  j 
)
static

Definition at line 1511 of file localtime.c.

1512{
1513#ifdef ckd_add
1514 return ckd_add(ip, *ip, j);
1515#else
1516 int const i = *ip;
1517
1518 /*----------
1519 * If i >= 0 there can only be overflow if i + j > INT_MAX
1520 * or if j > INT_MAX - i; given i >= 0, INT_MAX - i cannot overflow.
1521 * If i < 0 there can only be overflow if i + j < INT_MIN
1522 * or if j < INT_MIN - i; given i < 0, INT_MIN - i cannot overflow.
1523 *----------
1524 */
1525 if ((i >= 0) ? (j > INT_MAX - i) : (j < INT_MIN - i))
1526 return true;
1527 *ip += j;
1528 return false;
1529#endif
1530}
return true
Definition isn.c:130
int j
Definition isn.c:78

References fb(), i, and j.

Referenced by tzparse().

◆ increment_overflow_time()

static bool increment_overflow_time ( pg_time_t tp,
int_fast32_2s  j 
)
static

Definition at line 1533 of file localtime.c.

1534{
1535#ifdef ckd_add
1536 return ckd_add(tp, *tp, j);
1537#else
1538 /*----------
1539 * This is like
1540 * 'if (! (TIME_T_MIN <= *tp + j && *tp + j <= TIME_T_MAX)) ...',
1541 * except that it does the right thing even if *tp + j would overflow.
1542 *----------
1543 */
1544 if (!(j < 0
1545 ? (TYPE_SIGNED(pg_time_t) ? TIME_T_MIN - j <= *tp : -1 - j < *tp)
1546 : *tp <= TIME_T_MAX - j))
1547 return true;
1548 *tp += j;
1549 return false;
1550#endif
1551}
int64 pg_time_t
Definition pgtime.h:23
#define TIME_T_MAX
Definition private.h:170
#define TIME_T_MIN
Definition private.h:169
#define TYPE_SIGNED(type)
Definition private.h:145

References fb(), j, TIME_T_MAX, TIME_T_MIN, and TYPE_SIGNED.

Referenced by tzloadbody(), and tzparse().

◆ init_ttinfo()

static void init_ttinfo ( struct ttinfo s,
int_fast32_t  utoff,
bool  isdst,
desigidx_type  desigidx 
)
static

Definition at line 152 of file localtime.c.

154{
155 s->tt_utoff = utoff;
156 s->tt_isdst = isdst;
158 s->tt_ttisstd = false;
159 s->tt_ttisut = false;
160}
bool tt_ttisstd
Definition pgtz.h:53
bool tt_isdst
Definition pgtz.h:52
int_least32_t tt_utoff
Definition pgtz.h:49
desigidx_type tt_desigidx
Definition pgtz.h:51
bool tt_ttisut
Definition pgtz.h:54
static unsigned char desigidx[TZ_MAX_TYPES]
Definition zic.c:482

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

Referenced by tzparse().

◆ is_digit()

static bool is_digit ( char  c)
static

Definition at line 639 of file localtime.c.

640{
641 return '0' <= c && c <= '9';
642}

Referenced by getnum(), getrule(), and getzname().

◆ leapcorr()

static int_fast32_2s leapcorr ( struct state const sp,
pg_time_t  t 
)
static

Definition at line 1554 of file localtime.c.

1555{
1556 int i;
1557
1558 i = leapcount(sp);
1559 while (--i >= 0)
1560 {
1561 struct lsinfo ls = lsinfo(sp, i);
1562
1563 if (ls.ls_trans <= t)
1564 return ls.ls_corr;
1565 }
1566 return 0;
1567}
static int leapcount(ATTRIBUTE_MAYBE_UNUSED struct state const *sp)
Definition localtime.c:73
Definition pgtz.h:58

References fb(), i, and leapcount().

Referenced by tzloadbody().

◆ leapcount()

static int leapcount ( ATTRIBUTE_MAYBE_UNUSED struct state const sp)
static

Definition at line 73 of file localtime.c.

74{
75#if TZ_RUNTIME_LEAPS
76 return sp->leapcnt;
77#else
78 return 0;
79#endif
80}

References fb().

Referenced by leapcorr(), timesub(), tzloadbody(), and tzparse().

◆ leaps_thru_end_of()

static pg_time_t leaps_thru_end_of ( pg_time_t  y)
static

Definition at line 1350 of file localtime.c.

1351{
1352 return (y < 0
1353 ? -1 - leaps_thru_end_of_nonneg(-1 - y)
1355}
int y
Definition isn.c:76
static pg_time_t leaps_thru_end_of_nonneg(pg_time_t y)
Definition localtime.c:1344

References leaps_thru_end_of_nonneg(), and y.

Referenced by timesub().

◆ leaps_thru_end_of_nonneg()

static pg_time_t leaps_thru_end_of_nonneg ( pg_time_t  y)
static

Definition at line 1344 of file localtime.c.

1345{
1346 return y / 4 - y / 100 + y / 400;
1347}

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

1188{
1189 const struct ttinfo *ttisp;
1190 int i;
1191 struct pg_tm *result;
1192 const pg_time_t t = *timep;
1193
1194 if (sp == NULL)
1195 return gmtsub(timep, 0, tmp);
1196 if ((sp->goback && t < sp->ats[0]) ||
1197 (sp->goahead && t > sp->ats[sp->timecnt - 1]))
1198 {
1202
1203 if (t < sp->ats[0])
1204 seconds = sp->ats[0] - t;
1205 else
1206 seconds = t - sp->ats[sp->timecnt - 1];
1207 --seconds;
1208
1209 /*
1210 * Beware integer overflow, as SECONDS might be close to the maximum
1211 * pg_time_t.
1212 */
1216 if (t < sp->ats[0])
1217 newt = t + seconds + SECSPERREPEAT;
1218 else
1219 newt = t - seconds - SECSPERREPEAT;
1220
1221 if (newt < sp->ats[0] ||
1222 newt > sp->ats[sp->timecnt - 1])
1223 return NULL; /* "cannot happen" */
1224 result = localsub(sp, &newt, tmp);
1225 if (result)
1226 {
1227#if defined ckd_add && defined ckd_sub
1228 if (t < sp->ats[0]
1229 ? ckd_sub(&result->tm_year,
1230 result->tm_year, years)
1232 result->tm_year, years))
1233 return NULL;
1234#else
1236
1237 newy = result->tm_year;
1238 if (t < sp->ats[0])
1239 newy -= years;
1240 else
1241 newy += years;
1242 if (!(INT_MIN <= newy && newy <= INT_MAX))
1243 return NULL;
1244 result->tm_year = newy;
1245#endif
1246 }
1247 return result;
1248 }
1249 if (sp->timecnt == 0 || t < sp->ats[0])
1250 {
1251 i = 0;
1252 }
1253 else
1254 {
1255 int lo = 1;
1256 int hi = sp->timecnt;
1257
1258 while (lo < hi)
1259 {
1260 int mid = (lo + hi) >> 1;
1261
1262 if (t < sp->ats[mid])
1263 hi = mid;
1264 else
1265 lo = mid + 1;
1266 }
1267 i = sp->types[lo - 1];
1268 }
1269 ttisp = &sp->ttis[i];
1270
1271 /*
1272 * To get (wrong) behavior that's compatible with System V Release 2.0
1273 * you'd replace the statement below with t += ttisp->tt_utoff;
1274 * timesub(&t, 0, sp, tmp);
1275 */
1276 result = timesub(&t, ttisp->tt_utoff, sp, tmp);
1277 if (result)
1278 {
1279 result->tm_isdst = ttisp->tt_isdst;
1280#ifdef TM_ZONE
1281 result->TM_ZONE = UNCONST(&sp->chars[ttisp->tt_desigidx]);
1282#endif
1283 }
1284 return result;
1285}
static struct pg_tm * localsub(struct state const *sp, pg_time_t const *timep, struct pg_tm *const tmp)
Definition localtime.c:1186
static struct pg_tm * gmtsub(pg_time_t const *timep, int_fast32_t offset, struct pg_tm *tmp)
Definition localtime.c:1302
@ YEARSPERREPEAT
Definition private.h:217
#define SECSPERREPEAT
Definition private.h:223
#define AVGSECSPERYEAR
Definition private.h:224
int tm_year
Definition pgtime.h:41
Definition pgtz.h:48

References AVGSECSPERYEAR, fb(), gmtsub(), i, localsub(), result, SECSPERREPEAT, timesub(), UNCONST, and YEARSPERREPEAT.

Referenced by localsub(), and pg_localtime().

◆ lsinfo()

Definition at line 90 of file localtime.c.

92{
93#if TZ_RUNTIME_LEAPS
94 return sp->lsis[i];
95#else
97#endif
98}
#define unreachable()
Definition private.h:189

References fb(), i, and unreachable.

◆ pg_get_next_timezone_abbrev()

const char * pg_get_next_timezone_abbrev ( int indx,
const pg_tz tz 
)

Definition at line 1960 of file localtime.c.

1962{
1963 const char *result;
1964 const struct state *sp = &tz->state;
1965 const char *abbrs;
1966 int abbrind;
1967
1968 /* If we're still in range, the result is the current abbrev. */
1969 abbrs = sp->chars;
1970 abbrind = *indx;
1971 if (abbrind < 0 || abbrind >= sp->charcnt)
1972 return NULL;
1973 result = abbrs + abbrind;
1974
1975 /* Advance *indx past this abbrev and its trailing null. */
1976 while (abbrs[abbrind] != '\0')
1977 abbrind++;
1978 abbrind++;
1979 *indx = abbrind;
1980
1981 return result;
1982}
struct state state
Definition pgtz.h:108
char chars[Max(Max(TZ_MAX_CHARS+CHARS_EXTRA, sizeof "UTC"), 2 *(TZNAME_MAXIMUM+1))]
Definition pgtz.h:97

References state::chars, fb(), result, and pg_tz::state.

Referenced by pg_timezone_abbrevs_zone().

◆ pg_get_timezone_name()

const char * pg_get_timezone_name ( pg_tz tz)

Definition at line 2013 of file localtime.c.

2014{
2015 if (tz)
2016 return tz->TZname;
2017 return NULL;
2018}
char TZname[TZ_STRLEN_MAX+1]
Definition pgtz.h:107

References fb(), and pg_tz::TZname.

Referenced by pg_timezone_names(), 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 1989 of file localtime.c.

1990{
1991 /*
1992 * The zone could have more than one ttinfo, if it's historically used
1993 * more than one abbreviation. We return true as long as they all have
1994 * the same gmtoff.
1995 */
1996 const struct state *sp;
1997 int i;
1998
1999 sp = &tz->state;
2000 for (i = 1; i < sp->typecnt; i++)
2001 {
2002 if (sp->ttis[i].tt_utoff != sp->ttis[0].tt_utoff)
2003 return false;
2004 }
2005 *gmtoff = sp->ttis[0].tt_utoff;
2006 return true;
2007}
struct ttinfo ttis[TZ_MAX_TYPES]
Definition pgtz.h:95

References fb(), i, pg_tz::state, ttinfo::tt_utoff, and state::ttis.

Referenced by DecodeTimeOnly(), and TimestampTimestampTzRequiresRewrite().

◆ pg_gmtime()

struct pg_tm * pg_gmtime ( const pg_time_t timep)

Definition at line 1333 of file localtime.c.

1334{
1335 return gmtsub(timep, 0, &tm);
1336}
static struct pg_tm tm
Definition localtime.c:148

References fb(), 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 1767 of file localtime.c.

1772{
1773 const struct state *sp;
1774 const char *abbrs;
1775 const struct ttinfo *ttisp;
1776 int abbrind;
1777 int cutoff;
1778 int i;
1779 const pg_time_t t = *timep;
1780
1781 sp = &tz->state;
1782
1783 /*
1784 * Locate the abbreviation in the zone's abbreviation list. We assume
1785 * there are not duplicates in the list.
1786 */
1787 abbrs = sp->chars;
1788 abbrind = 0;
1789 while (abbrind < sp->charcnt)
1790 {
1791 if (strcmp(abbrev, abbrs + abbrind) == 0)
1792 break;
1793 while (abbrs[abbrind] != '\0')
1794 abbrind++;
1795 abbrind++;
1796 }
1797 if (abbrind >= sp->charcnt)
1798 return false; /* not there! */
1799
1800 /*
1801 * Unlike pg_next_dst_boundary, we needn't sweat about extrapolation
1802 * (goback/goahead zones). Finding the newest or oldest meaning of the
1803 * abbreviation should get us what we want, since extrapolation would just
1804 * be repeating the newest or oldest meanings.
1805 *
1806 * Use binary search to locate the first transition > cutoff time. (Note
1807 * that sp->timecnt could be zero, in which case this loop does nothing
1808 * and only the defaulttype entry will be checked.)
1809 */
1810 {
1811 int lo = 0;
1812 int hi = sp->timecnt;
1813
1814 while (lo < hi)
1815 {
1816 int mid = (lo + hi) >> 1;
1817
1818 if (t < sp->ats[mid])
1819 hi = mid;
1820 else
1821 lo = mid + 1;
1822 }
1823 cutoff = lo;
1824 }
1825
1826 /*
1827 * Scan backwards to find the latest interval using the given abbrev
1828 * before the cutoff time.
1829 */
1830 for (i = cutoff - 1; i >= 0; i--)
1831 {
1832 ttisp = &sp->ttis[sp->types[i]];
1833 if (ttisp->tt_desigidx == abbrind)
1834 {
1835 *gmtoff = ttisp->tt_utoff;
1836 *isdst = ttisp->tt_isdst;
1837 return true;
1838 }
1839 }
1840
1841 /*
1842 * Not found yet; check the defaulttype, which is notionally the era
1843 * before any of the entries in sp->types[].
1844 */
1845 ttisp = &sp->ttis[0];
1846 if (ttisp->tt_desigidx == abbrind)
1847 {
1848 *gmtoff = ttisp->tt_utoff;
1849 *isdst = ttisp->tt_isdst;
1850 return true;
1851 }
1852
1853 /*
1854 * Not there, so scan forwards to find the first one after the cutoff.
1855 */
1856 for (i = cutoff; i < sp->timecnt; i++)
1857 {
1858 ttisp = &sp->ttis[sp->types[i]];
1859 if (ttisp->tt_desigidx == abbrind)
1860 {
1861 *gmtoff = ttisp->tt_utoff;
1862 *isdst = ttisp->tt_isdst;
1863 return true;
1864 }
1865 }
1866
1867 return false; /* hm, not actually used in any interval? */
1868}
static int charcnt
Definition zic.c:222

References charcnt, state::chars, fb(), i, and pg_tz::state.

Referenced by DetermineTimeZoneAbbrevOffsetInternal(), and pg_timezone_abbrevs_zone().

◆ pg_localtime()

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

1641{
1642 const struct state *sp;
1643 const struct ttinfo *ttisp;
1644 int i;
1645 int j;
1646 const pg_time_t t = *timep;
1647
1648 sp = &tz->state;
1649 if (sp->timecnt == 0)
1650 {
1651 /* non-DST zone, use the defaulttype (now always 0) */
1652 ttisp = &sp->ttis[0];
1654 *before_isdst = ttisp->tt_isdst;
1655 return 0;
1656 }
1657 if ((sp->goback && t < sp->ats[0]) ||
1658 (sp->goahead && t > sp->ats[sp->timecnt - 1]))
1659 {
1660 /* For values outside the transition table, extrapolate */
1661 pg_time_t newt = t;
1664 int64 icycles;
1665 int result;
1666
1667 if (t < sp->ats[0])
1668 seconds = sp->ats[0] - t;
1669 else
1670 seconds = t - sp->ats[sp->timecnt - 1];
1671 --seconds;
1673 ++tcycles;
1674 icycles = tcycles;
1675 if (tcycles - icycles >= 1 || icycles - tcycles >= 1)
1676 return -1;
1677 seconds = icycles;
1680 if (t < sp->ats[0])
1681 newt += seconds;
1682 else
1683 newt -= seconds;
1684 if (newt < sp->ats[0] ||
1685 newt > sp->ats[sp->timecnt - 1])
1686 return -1; /* "cannot happen" */
1687
1690 boundary,
1693 tz);
1694 if (t < sp->ats[0])
1695 *boundary -= seconds;
1696 else
1697 *boundary += seconds;
1698 return result;
1699 }
1700
1701 if (t >= sp->ats[sp->timecnt - 1])
1702 {
1703 /* No known transition > t, so use last known segment's type */
1704 i = sp->types[sp->timecnt - 1];
1705 ttisp = &sp->ttis[i];
1706 *before_gmtoff = ttisp->tt_utoff;
1707 *before_isdst = ttisp->tt_isdst;
1708 return 0;
1709 }
1710 if (t < sp->ats[0])
1711 {
1712 /* For "before", use the defaulttype (now always 0) */
1713 ttisp = &sp->ttis[0];
1714 *before_gmtoff = ttisp->tt_utoff;
1715 *before_isdst = ttisp->tt_isdst;
1716 *boundary = sp->ats[0];
1717 /* And for "after", use the first segment's type */
1718 i = sp->types[0];
1719 ttisp = &sp->ttis[i];
1720 *after_gmtoff = ttisp->tt_utoff;
1721 *after_isdst = ttisp->tt_isdst;
1722 return 1;
1723 }
1724 /* Else search to find the boundary following t */
1725 {
1726 int lo = 1;
1727 int hi = sp->timecnt - 1;
1728
1729 while (lo < hi)
1730 {
1731 int mid = (lo + hi) >> 1;
1732
1733 if (t < sp->ats[mid])
1734 hi = mid;
1735 else
1736 lo = mid + 1;
1737 }
1738 i = lo;
1739 }
1740 j = sp->types[i - 1];
1741 ttisp = &sp->ttis[j];
1742 *before_gmtoff = ttisp->tt_utoff;
1743 *before_isdst = ttisp->tt_isdst;
1744 *boundary = sp->ats[i];
1745 j = sp->types[i];
1746 ttisp = &sp->ttis[j];
1747 *after_gmtoff = ttisp->tt_utoff;
1748 *after_isdst = ttisp->tt_isdst;
1749 return 1;
1750}
int64_t int64
Definition c.h:680
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:1634

References AVGSECSPERYEAR, fb(), i, j, pg_next_dst_boundary(), result, pg_tz::state, ttinfo::tt_utoff, state::ttis, and YEARSPERREPEAT.

Referenced by DetermineTimeZoneOffsetInternal(), and pg_next_dst_boundary().

◆ pg_timezone_abbrev_is_known()

bool pg_timezone_abbrev_is_known ( const char abbrev,
bool isfixed,
long int gmtoff,
int isdst,
const pg_tz tz 
)

Definition at line 1885 of file localtime.c.

1890{
1891 bool result = false;
1892 const struct state *sp = &tz->state;
1893 const char *abbrs;
1894 int abbrind;
1895
1896 /*
1897 * Locate the abbreviation in the zone's abbreviation list. We assume
1898 * there are not duplicates in the list.
1899 */
1900 abbrs = sp->chars;
1901 abbrind = 0;
1902 while (abbrind < sp->charcnt)
1903 {
1904 if (strcmp(abbrev, abbrs + abbrind) == 0)
1905 break;
1906 while (abbrs[abbrind] != '\0')
1907 abbrind++;
1908 abbrind++;
1909 }
1910 if (abbrind >= sp->charcnt)
1911 return false; /* definitely not there */
1912
1913 /*
1914 * Scan the ttinfo array to find uses of the abbreviation.
1915 */
1916 for (int i = 0; i < sp->typecnt; i++)
1917 {
1918 const struct ttinfo *ttisp = &sp->ttis[i];
1919
1920 if (ttisp->tt_desigidx == abbrind)
1921 {
1922 if (!result)
1923 {
1924 /* First usage */
1925 *isfixed = true; /* for the moment */
1926 *gmtoff = ttisp->tt_utoff;
1927 *isdst = ttisp->tt_isdst;
1928 result = true;
1929 }
1930 else
1931 {
1932 /* Second or later usage, does it match? */
1933 if (*gmtoff != ttisp->tt_utoff ||
1934 *isdst != ttisp->tt_isdst)
1935 {
1936 *isfixed = false;
1937 break; /* no point in looking further */
1938 }
1939 }
1940 }
1941 }
1942
1943 return result;
1944}

References charcnt, state::chars, fb(), i, result, pg_tz::state, and ttinfo::tt_utoff.

Referenced by TimeZoneAbbrevIsKnown().

◆ pg_tz_acceptable()

bool pg_tz_acceptable ( pg_tz tz)

Definition at line 2028 of file localtime.c.

2029{
2030 struct pg_tm *tt;
2032
2033 /*
2034 * To detect leap-second timekeeping, run pg_localtime for what should be
2035 * GMT midnight, 2000-01-01. Insist that the tm_sec value be zero; any
2036 * other result has to be due to leap seconds.
2037 */
2039 tt = pg_localtime(&time2000, tz);
2040 if (!tt || tt->tm_sec != 0)
2041 return false;
2042
2043 return true;
2044}
#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:1289

References fb(), pg_localtime(), POSTGRES_EPOCH_JDATE, SECS_PER_DAY, and UNIX_EPOCH_JDATE.

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

◆ pg_tzload()

bool pg_tzload ( const char name,
char canonname,
struct state sp 
)

Definition at line 1590 of file localtime.c.

1591{
1592 if (strcmp(name, "GMT") == 0)
1593 {
1594 gmtload(sp);
1595 /* Use given name as canonical */
1596 if (canonname)
1598 }
1599 else if (tzload(name, canonname, sp, TZLOAD_TZSTRING) != 0)
1600 {
1601 if (name[0] == ':' || !tzparse(name, sp, NULL))
1602 {
1603 /* Unknown timezone. Fail our call instead of loading GMT! */
1604 return false;
1605 }
1606 /* For POSIX timezone specs, use given name as canonical */
1607 if (canonname)
1609 }
1610 return true;
1611}
static int tzload(char const *name, char *canonname, struct state *sp, char tzloadflags)
Definition localtime.c:618
const char * name

References fb(), gmtload(), name, tzload(), TZLOAD_TZSTRING, and tzparse().

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

◆ set_leapcount()

static void set_leapcount ( ATTRIBUTE_MAYBE_UNUSED struct state sp,
ATTRIBUTE_MAYBE_UNUSED int  leapcnt 
)
static

Definition at line 82 of file localtime.c.

84{
85#if TZ_RUNTIME_LEAPS
86 sp->leapcnt = leapcnt;
87#endif
88}
static ptrdiff_t leapcnt
Definition zic.c:226

References fb(), and leapcnt.

Referenced by tzloadbody(), and tzparse().

◆ set_lsinfo()

static void set_lsinfo ( ATTRIBUTE_MAYBE_UNUSED struct state sp,
ATTRIBUTE_MAYBE_UNUSED int  i,
ATTRIBUTE_MAYBE_UNUSED struct lsinfo  lsinfo 
)
static

Definition at line 100 of file localtime.c.

103{
104#if TZ_RUNTIME_LEAPS
105 sp->lsis[i] = lsinfo;
106#endif
107}

References fb(), and i.

Referenced by tzloadbody(), and tzparse().

◆ timesub()

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

Definition at line 1358 of file localtime.c.

1360{
1362 const int *ip;
1364 int i;
1366 rem,
1367 dayoff,
1368 dayrem;
1369 pg_time_t y;
1370
1371 /*
1372 * If less than SECSPERMIN, the number of seconds since the most recent
1373 * positive leap second; otherwise, do not add 1 to localtime tm_sec
1374 * because of leap seconds.
1375 */
1377
1378 corr = 0;
1379 i = sp ? leapcount(sp) : 0;
1380 while (--i >= 0)
1381 {
1382 struct lsinfo ls = lsinfo(sp, i);
1383
1384 if (ls.ls_trans <= *timep)
1385 {
1386 corr = ls.ls_corr;
1387 if ((i == 0 ? 0 : lsinfo(sp, i - 1).ls_corr) < corr)
1389 break;
1390 }
1391 }
1392
1393 /*
1394 * Calculate the year, avoiding integer overflow even if pg_time_t is
1395 * unsigned.
1396 */
1397 tdays = *timep / SECSPERDAY;
1398 rem = *timep % SECSPERDAY;
1399 rem += offset % SECSPERDAY - corr % SECSPERDAY + 3 * SECSPERDAY;
1400 dayoff = offset / SECSPERDAY - corr / SECSPERDAY + rem / SECSPERDAY - 3;
1401 rem %= SECSPERDAY;
1402
1403 /*
1404 * y = (EPOCH_YEAR + floor((tdays + dayoff) / DAYSPERREPEAT) *
1405 * YEARSPERREPEAT), sans overflow. But calculate against 1570 (EPOCH_YEAR
1406 * - YEARSPERREPEAT) instead of against 1970 so that things work for
1407 * localtime values before 1970 when pg_time_t is unsigned.
1408 */
1413 - ((dayrem % DAYSPERREPEAT) < 0)
1414 + tdays / DAYSPERREPEAT)
1415 * YEARSPERREPEAT));
1416 /* idays = (tdays + dayoff) mod DAYSPERREPEAT, sans overflow. */
1420 /* Increase Y and decrease IDAYS until IDAYS is in range for Y. */
1421 while (year_lengths[isleap(y)] <= idays)
1422 {
1423 int tdelta = idays / DAYSPERLYEAR;
1425 pg_time_t newy = y + ydelta;
1426 int leapdays;
1427
1429 leaps_thru_end_of(y - 1);
1431 idays -= leapdays;
1432 y = newy;
1433 }
1434
1435#ifdef ckd_add
1436 if (ckd_add(&tmp->tm_year, y, -TM_YEAR_BASE))
1437 {
1438 errno = EOVERFLOW;
1439 return NULL;
1440 }
1441#else
1443 {
1444 int signed_y = y;
1445
1446 tmp->tm_year = signed_y - TM_YEAR_BASE;
1447 }
1448 else if ((!TYPE_SIGNED(pg_time_t) || INT_MIN + TM_YEAR_BASE <= y)
1449 && y - TM_YEAR_BASE <= INT_MAX)
1450 tmp->tm_year = y - TM_YEAR_BASE;
1451 else
1452 {
1453 errno = EOVERFLOW;
1454 return NULL;
1455 }
1456#endif
1457 tmp->tm_yday = idays;
1458
1459 /*
1460 * The "extra" mods below avoid overflow problems.
1461 */
1462 tmp->tm_wday = (TM_WDAY_BASE
1463 + ((tmp->tm_year % DAYSPERWEEK)
1465 + leaps_thru_end_of(y - 1)
1467 + idays);
1468 tmp->tm_wday %= DAYSPERWEEK;
1469 if (tmp->tm_wday < 0)
1470 tmp->tm_wday += DAYSPERWEEK;
1471 tmp->tm_hour = rem / SECSPERHOUR;
1472 rem %= SECSPERHOUR;
1473 tmp->tm_min = rem / SECSPERMIN;
1474 tmp->tm_sec = rem % SECSPERMIN;
1475
1476 /*
1477 * Use "... ??:??:60" at the end of the localtime minute containing the
1478 * second just before the positive leap second.
1479 */
1480 tmp->tm_sec += secs_since_posleap <= tmp->tm_sec;
1481
1482 ip = mon_lengths[isleap(y)];
1483 for (tmp->tm_mon = 0; idays >= ip[tmp->tm_mon]; ++(tmp->tm_mon))
1484 idays -= ip[tmp->tm_mon];
1485 tmp->tm_mday = idays + 1;
1486 tmp->tm_isdst = 0;
1487#ifdef TM_GMTOFF
1488 tmp->TM_GMTOFF = offset;
1489#endif /* defined TM_GMTOFF */
1490 return tmp;
1491}
#define isleap(y)
Definition datetime.h:273
static pg_time_t leaps_thru_end_of(pg_time_t y)
Definition localtime.c:1350
static const int year_lengths[2]
Definition localtime.c:633
static const int mon_lengths[2][MONSPERYEAR]
Definition localtime.c:628
#define SECSPERDAY
Definition private.h:220
#define EOVERFLOW
Definition private.h:88
@ TM_WDAY_BASE
Definition private.h:273
@ EPOCH_YEAR
Definition private.h:274
@ TM_YEAR_BASE
Definition private.h:272
#define DAYSPERREPEAT
Definition private.h:222
pg_time_t ls_trans
Definition pgtz.h:59
int_fast32_2s ls_corr
Definition pgtz.h:60
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
int tm_sec
Definition pgtime.h:36
int tm_isdst
Definition pgtime.h:44
zic_t corr
Definition zic.c:489

References corr, DAYSPERLYEAR, DAYSPERNYEAR, DAYSPERREPEAT, DAYSPERWEEK, EOVERFLOW, EPOCH_YEAR, fb(), i, isleap, leapcount(), leaps_thru_end_of(), lsinfo::ls_corr, mon_lengths, SECSPERDAY, SECSPERHOUR, SECSPERMIN, 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, TM_WDAY_BASE, pg_tm::tm_yday, pg_tm::tm_year, TM_YEAR_BASE, TYPE_SIGNED, y, year_lengths, and YEARSPERREPEAT.

Referenced by gmtsub(), and localsub().

◆ transtime()

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

Definition at line 850 of file localtime.c.

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

References DAY_OF_YEAR, DAYSPERWEEK, fb(), i, isleap, JULIAN_DAY, mon_lengths, MONTH_NTH_DAY_OF_WEEK, SECSPERDAY, unreachable, and value.

Referenced by tzparse().

◆ tzload()

static int tzload ( char const name,
char canonname,
struct state sp,
char  tzloadflags 
)
static

Definition at line 618 of file localtime.c.

619{
620 /* PG: our version of tzloadbody never reallocates *lspp */
621 union local_storage *lsp;
622 union local_storage ls;
623
624 lsp = &ls;
626}
static int tzloadbody(char const *name, char *canonname, struct state *sp, char tzloadflags, union local_storage **lspp)
Definition localtime.c:261

References fb(), name, and tzloadbody().

Referenced by pg_tzload().

◆ tzloadbody()

static int tzloadbody ( char const name,
char canonname,
struct state sp,
char  tzloadflags,
union local_storage **  lspp 
)
static

Definition at line 261 of file localtime.c.

264{
265 int i;
266 int fid;
267 int stored;
269 union local_storage *lsp = *lspp;
270 union input_buffer *up;
271 int tzheadsize = sizeof(struct tzhead);
272
273 sp->goback = sp->goahead = false;
274
275 if (!name)
276 {
277 name = TZDEFAULT;
278 if (!name)
279 return EINVAL;
280 }
281
282 if (name[0] == ':')
283 ++name;
284
285 /*
286 * The IANA code goes to a great deal of trouble here to try to prevent
287 * inappropriate file accesses. That seems unnecessary for PG since we
288 * won't run as root. pg_open_tzfile() does go to some effort to prevent
289 * accesses outside the designated zoneinfo tree, though.
290 */
292 if (fid < 0)
293 return ENOENT; /* pg_open_tzfile may not set errno */
294
295 up = &lsp->u.u;
296 nread = read(fid, up->buf, sizeof up->buf);
297 if (nread < tzheadsize)
298 {
299 int err = nread < 0 ? errno : EINVAL;
300
301 close(fid);
302 return err;
303 }
304 if (close(fid) < 0)
305 return errno;
306
307 for (stored = 4; stored <= 8; stored *= 2)
308 {
309 char version = up->tzhead.tzh_version[0];
310 bool skip_datablock = stored == 4 && version;
313 ttisstdcnt = detzcode(up->tzhead.tzh_ttisstdcnt),
314 ttisutcnt = detzcode(up->tzhead.tzh_ttisutcnt),
315 leapcnt = detzcode(up->tzhead.tzh_leapcnt),
316 timecnt = detzcode(up->tzhead.tzh_timecnt),
317 typecnt = detzcode(up->tzhead.tzh_typecnt),
318 charcnt = detzcode(up->tzhead.tzh_charcnt);
319 char const *p = up->buf + tzheadsize;
320
321 /*
322 * Although tzfile(5) currently requires typecnt to be nonzero,
323 * support future formats that may allow zero typecnt in files that
324 * have a TZ string and no transitions.
325 */
326 if (!(0 <= leapcnt
328 && 0 <= typecnt && typecnt <= TZ_MAX_TYPES
329 && 0 <= timecnt && timecnt <= TZ_MAX_TIMES
330 && 0 <= charcnt && charcnt <= TZ_MAX_CHARS
332 && 0 <= ttisutcnt && ttisutcnt <= TZ_MAX_TYPES))
335 = (timecnt * stored /* ats */
336 + timecnt /* types */
337 + typecnt * 6 /* ttinfos */
338 + charcnt /* chars */
339 + leapcnt * (stored + 4) /* lsinfos */
340 + ttisstdcnt /* ttisstds */
341 + ttisutcnt); /* ttisuts */
343 return EINVAL;
344 if (skip_datablock)
345 p += datablock_size;
346 else if (!((ttisstdcnt == typecnt || ttisstdcnt == 0)
347 && (ttisutcnt == typecnt || ttisutcnt == 0)))
348 return EINVAL;
349 else
350 {
351 int_fast64_t prevtr = -1;
353
355 sp->timecnt = timecnt;
356 sp->typecnt = typecnt;
357 sp->charcnt = charcnt;
358
359 /*
360 * Read transitions, discarding those out of pg_time_t range. But
361 * pretend the last transition before TIME_T_MIN occurred at
362 * TIME_T_MIN.
363 */
364 timecnt = 0;
365 for (i = 0; i < sp->timecnt; ++i)
366 {
367 int_fast64_t at
368 = stored == 4 ? detzcode(p) : detzcode64(p);
369
370 sp->types[i] = at <= TIME_T_MAX;
371 if (sp->types[i])
372 {
374 = ((TYPE_SIGNED(pg_time_t) ? at < TIME_T_MIN : at < 0)
375 ? TIME_T_MIN : at);
376
377 if (timecnt && attime <= sp->ats[timecnt - 1])
378 {
379 if (attime < sp->ats[timecnt - 1])
380 return EINVAL;
381 sp->types[i - 1] = 0;
382 timecnt--;
383 }
384 sp->ats[timecnt++] = attime;
385 }
386 p += stored;
387 }
388
389 timecnt = 0;
390 for (i = 0; i < sp->timecnt; ++i)
391 {
392 unsigned char typ = *p++;
393
394 if (sp->typecnt <= typ)
395 return EINVAL;
396 if (sp->types[i])
397 sp->types[timecnt++] = typ;
398 }
399 sp->timecnt = timecnt;
400 for (i = 0; i < sp->typecnt; ++i)
401 {
402 struct ttinfo *ttisp;
403 unsigned char isdst,
404 desigidx;
406
407 /*
408 * Reject a UT offset equal to -2**31, as it might cause
409 * trouble both in this file and in callers. Also, it violates
410 * RFC 9636 section 3.2.
411 */
412 if (utoff < -TWO_31_MINUS_1)
413 return EINVAL;
414
415 ttisp = &sp->ttis[i];
416 ttisp->tt_utoff = utoff;
417 p += 4;
418 isdst = *p++;
419 if (!(isdst < 2))
420 return EINVAL;
421 ttisp->tt_isdst = isdst;
422 desigidx = *p++;
424 return EINVAL;
425 ttisp->tt_desigidx = desigidx;
426 }
427 for (i = 0; i < sp->charcnt; ++i)
428 sp->chars[i] = *p++;
429
430 /*
431 * Ensure '\0'-terminated, and make it safe to call ttunspecified
432 * later.
433 */
434 memset(&sp->chars[i], 0, CHARS_EXTRA);
435
436 /* Read leap seconds, discarding those out of pg_time_t range. */
437 leapcnt = 0;
438 for (i = 0; i < leapcount(sp); i++)
439 {
440 int_fast64_t tr = stored == 4 ? detzcode(p) : detzcode64(p);
442
443 p += stored + 4;
444
445 /*
446 * Leap seconds cannot occur before the Epoch, or out of
447 * order.
448 */
449 if (tr <= prevtr)
450 return EINVAL;
451
452 /*
453 * To avoid other botches in this code, each leap second's
454 * correction must differ from the previous one's by 1 second
455 * or less, except that the first correction can be any value;
456 * these requirements are more generous than RFC 9636, to
457 * allow future RFC extensions.
458 */
459 if (!(i == 0
460 || (prevcorr < corr
461 ? corr == prevcorr + 1
462 : (corr == prevcorr
463 || corr == prevcorr - 1))))
465 prevtr = tr;
466 prevcorr = corr;
467
468 if (tr <= TIME_T_MAX)
469 {
470 struct lsinfo ls;
471
472 ls.ls_trans = tr;
473 ls.ls_corr = corr;
475 leapcnt++;
476 }
477 }
479
480 for (i = 0; i < sp->typecnt; ++i)
481 {
482 struct ttinfo *ttisp;
483
484 ttisp = &sp->ttis[i];
485 if (ttisstdcnt == 0)
486 ttisp->tt_ttisstd = false;
487 else
488 {
489 if (*p != true && *p != false)
490 return EINVAL;
491 ttisp->tt_ttisstd = *p++;
492 }
493 }
494 for (i = 0; i < sp->typecnt; ++i)
495 {
496 struct ttinfo *ttisp;
497
498 ttisp = &sp->ttis[i];
499 if (ttisutcnt == 0)
500 ttisp->tt_ttisut = false;
501 else
502 {
503 if (*p != true && *p != false)
504 return EINVAL;
505 ttisp->tt_ttisut = *p++;
506 }
507 }
508 }
509
510 nread -= p - up->buf;
511 memmove(up->buf, p, nread);
512
513 /* If this is an old file, we're done. */
514 if (!version)
515 break;
516 }
517 if ((tzloadflags & TZLOAD_TZSTRING) && nread > 2 &&
518 up->buf[0] == '\n' && up->buf[nread - 1] == '\n' &&
519 sp->typecnt + 2 <= TZ_MAX_TYPES)
520 {
521 struct state *ts = &lsp->u.st;
522
523 up->buf[nread - 1] = '\0';
524 if (tzparse(&up->buf[1], ts, sp))
525 {
526
527 /*
528 * Attempt to reuse existing abbreviations. Without this,
529 * America/Anchorage would consume 50 bytes for abbreviations, as
530 * sp->charcnt equals 40 (for LMT AST AWT APT AHST AHDT YST AKDT
531 * AKST) and ts->charcnt equals 10 (for AKST AKDT). Reusing means
532 * sp->charcnt can stay 40 in this example.
533 */
534 int gotabbr = 0;
535 int charcnt = sp->charcnt;
536
537 for (i = 0; i < ts->typecnt; i++)
538 {
539 char *tsabbr = ts->chars + ts->ttis[i].tt_desigidx;
540 int j;
541
542 for (j = 0; j < charcnt; j++)
543 if (strcmp(sp->chars + j, tsabbr) == 0)
544 {
545 ts->ttis[i].tt_desigidx = j;
546 gotabbr++;
547 break;
548 }
549 if (!(j < charcnt))
550 {
552
553 if (j + tsabbrlen < TZ_MAX_CHARS)
554 {
555 char *cp = sp->chars + j;
556
558 cp += tsabbrlen;
559 *cp = '\0';
560 charcnt = j + tsabbrlen + 1;
561 ts->ttis[i].tt_desigidx = j;
562 gotabbr++;
563 }
564 }
565 }
566 if (gotabbr == ts->typecnt)
567 {
568 sp->charcnt = charcnt;
569
570 /*
571 * Ignore any trailing, no-op transitions generated by zic as
572 * they don't help here and can run afoul of bugs in zic 2016j
573 * or earlier.
574 */
575 while (1 < sp->timecnt
576 && (sp->types[sp->timecnt - 1]
577 == sp->types[sp->timecnt - 2]))
578 sp->timecnt--;
579
580 sp->goahead = ts->goahead;
581
582 for (i = 0; i < ts->timecnt; i++)
583 {
584 pg_time_t t = ts->ats[i];
585
587 || (0 < sp->timecnt
588 && t <= sp->ats[sp->timecnt - 1]))
589 continue;
591 {
592 sp->goahead = false;
593 break;
594 }
595 sp->ats[sp->timecnt] = t;
596 sp->types[sp->timecnt] = (sp->typecnt
597 + ts->types[i]);
598 sp->timecnt++;
599 }
600 for (i = 0; i < ts->typecnt; i++)
601 sp->ttis[sp->typecnt++] = ts->ttis[i];
602 }
603 }
604 }
605 if (sp->typecnt == 0)
606 return EINVAL;
607
608 return 0;
609}
memcpy(sums, checksumBaseOffsets, sizeof(checksumBaseOffsets))
void err(int eval, const char *fmt,...)
Definition err.c:43
int pg_open_tzfile(const char *name, char *canonname)
#define close(a)
Definition win32.h:12
#define read(a, b, c)
Definition win32.h:13
static int_fast32_2s detzcode(const char *const codep)
Definition localtime.c:163
static bool increment_overflow_time(pg_time_t *tp, int_fast32_2s j)
Definition localtime.c:1533
static int_fast32_2s leapcorr(struct state const *sp, pg_time_t t)
Definition localtime.c:1554
static int_fast64_t detzcode64(const char *const codep)
Definition localtime.c:187
static void set_leapcount(ATTRIBUTE_MAYBE_UNUSED struct state *sp, ATTRIBUTE_MAYBE_UNUSED int leapcnt)
Definition localtime.c:82
static void set_lsinfo(ATTRIBUTE_MAYBE_UNUSED struct state *sp, ATTRIBUTE_MAYBE_UNUSED int i, ATTRIBUTE_MAYBE_UNUSED struct lsinfo lsinfo)
Definition localtime.c:100
#define TZ_RUNTIME_LEAPS
Definition pgtz.h:26
@ CHARS_EXTRA
Definition pgtz.h:74
#define EINVAL
Definition private.h:69
#define TZDEFAULT
Definition private.h:27
int timecnt
Definition pgtz.h:88
int charcnt
Definition pgtz.h:90
int typecnt
Definition pgtz.h:89
pg_time_t ats[TZ_MAX_TIMES]
Definition pgtz.h:93
unsigned char types[TZ_MAX_TIMES]
Definition pgtz.h:94
bool goahead
Definition pgtz.h:92
#define TZ_MAX_CHARS
Definition tzfile.h:112
#define TZ_MAX_TYPES
Definition tzfile.h:107
#define TZ_MAX_TIMES
Definition tzfile.h:102
#define TZ_MAX_LEAPS
Definition tzfile.h:122
static int typecnt
Definition zic.c:247
static ptrdiff_t timecnt
Definition zic.c:245

References state::ats, state::charcnt, charcnt, state::chars, CHARS_EXTRA, close, corr, desigidx, detzcode(), detzcode64(), EINVAL, err(), fb(), state::goahead, i, increment_overflow_time(), j, leapcnt, leapcorr(), leapcount(), lsinfo::ls_trans, memcpy(), name, pg_open_tzfile(), read, set_leapcount(), set_lsinfo(), TIME_T_MAX, TIME_T_MIN, state::timecnt, timecnt, ttinfo::tt_desigidx, ttinfo::tt_ttisstd, ttinfo::tt_ttisut, state::ttis, TWO_31_MINUS_1, TYPE_SIGNED, state::typecnt, typecnt, state::types, TZ_MAX_CHARS, TZ_MAX_LEAPS, TZ_MAX_TIMES, TZ_MAX_TYPES, TZ_RUNTIME_LEAPS, TZDEFAULT, TZLOAD_TZSTRING, and tzparse().

Referenced by tzload().

◆ tzparse()

static bool tzparse ( const char name,
struct state sp,
struct state const basep 
)
static

Definition at line 949 of file localtime.c.

950{
951 const char *stdname;
952 const char *dstname = NULL;
955 char *cp;
957 dstlen,
958 charcnt;
961
962 stdname = name;
963 if (*name == '<')
964 {
965 name++;
966 stdname = name;
967 name = getqzname(name, '>');
968 if (*name != '>')
969 return false;
970 stdlen = name - stdname;
971 name++;
972 }
973 else
974 {
975 name = getzname(name);
976 stdlen = name - stdname;
977 }
978 if (stdlen > TZNAME_MAXIMUM) /* allow empty STD abbrev, unlike IANA */
979 return false;
981 if (name == NULL)
982 return false;
983 charcnt = stdlen + 1;
984 if (basep)
985 {
986 if (0 < basep->timecnt)
987 atlo = basep->ats[basep->timecnt - 1];
989 if (0 < leapcount(sp))
990 {
991 int i;
992
993 for (i = 0; i < leapcount(sp); i++)
996 }
997 }
998 else
999 set_leapcount(sp, 0); /* So, we're off a little. */
1000 sp->goback = sp->goahead = false;
1001 if (*name != '\0')
1002 {
1003 struct rule start,
1004 end;
1005 int year,
1006 yearbeg,
1007 yearlim,
1008 timecnt;
1011
1012 if (*name == '<')
1013 {
1014 dstname = ++name;
1015 name = getqzname(name, '>');
1016 if (*name != '>')
1017 return false;
1018 dstlen = name - dstname;
1019 name++;
1020 }
1021 else
1022 {
1023 dstname = name;
1024 name = getzname(name);
1025 dstlen = name - dstname; /* length of DST abbr. */
1026 }
1027 if (!(0 < dstlen && dstlen <= TZNAME_MAXIMUM))
1028 return false;
1029 charcnt += dstlen + 1;
1030 if (*name != '\0' && *name != ',' && *name != ';')
1031 {
1033 if (name == NULL)
1034 return false;
1035 }
1036 else
1038
1039 if (*name == '\0')
1041 if (!(*name == ',' || *name == ';'))
1042 return false;
1043
1044 name = getrule(name + 1, &start);
1045 if (!name)
1046 return false;
1047 if (*name++ != ',')
1048 return false;
1049 name = getrule(name, &end);
1050 if (!name || *name)
1051 return false;
1052 sp->typecnt = 2; /* standard time and DST */
1053
1054 /*
1055 * Two transitions per year, from EPOCH_YEAR forward.
1056 */
1057 init_ttinfo(&sp->ttis[0], -stdoffset, false, 0);
1058 init_ttinfo(&sp->ttis[1], -dstoffset, true, stdlen + 1);
1059 timecnt = 0;
1060 janfirst = 0;
1062
1063 do
1064 {
1068
1069 yearbeg--;
1071 {
1073 break;
1074 }
1076 } while (atlo < janfirst
1077 && EPOCH_YEAR - YEARSPERREPEAT / 2 < yearbeg);
1078
1079 while (true)
1080 {
1083 int yearbeg1 = yearbeg;
1085
1088 || atlo <= janfirst1)
1089 break;
1090 yearbeg = yearbeg1;
1092 }
1093
1094 yearlim = yearbeg;
1096 yearlim = INT_MAX;
1097 for (year = yearbeg; year < yearlim; year++)
1098 {
1100 starttime = transtime(year, &start, stdoffset),
1101 endtime = transtime(year, &end, dstoffset),
1103 bool reversed = endtime < starttime;
1104
1105 if (reversed)
1106 {
1107 int_fast32_t swap = starttime;
1108
1109 starttime = endtime;
1110 endtime = swap;
1111 }
1112 if (reversed
1113 || (starttime < endtime
1114 && endtime - starttime < yearsecs))
1115 {
1116 if (TZ_MAX_TIMES - 2 < timecnt)
1117 break;
1118 sp->ats[timecnt] = janfirst;
1120 janoffset + starttime)
1121 && atlo <= sp->ats[timecnt])
1122 sp->types[timecnt++] = !reversed;
1123 sp->ats[timecnt] = janfirst;
1126 && atlo <= sp->ats[timecnt])
1127 {
1128 sp->types[timecnt++] = reversed;
1129 }
1130 }
1131 if (endtime < leaplo)
1132 {
1133 yearlim = year;
1135 yearlim = INT_MAX;
1136 }
1138 break;
1139 janoffset = 0;
1140 }
1141 sp->timecnt = timecnt;
1142 if (!timecnt)
1143 {
1144 sp->ttis[0] = sp->ttis[1];
1145 sp->typecnt = 1; /* Perpetual DST. */
1146 }
1147 else if (years_of_observations <= year - yearbeg)
1148 sp->goback = sp->goahead = true;
1149 }
1150 else
1151 {
1152 dstlen = 0;
1153 sp->typecnt = 1; /* only standard time */
1154 sp->timecnt = 0;
1155 init_ttinfo(&sp->ttis[0], -stdoffset, false, 0);
1156 }
1157 sp->charcnt = charcnt;
1158 cp = sp->chars;
1160 cp += stdlen;
1161 *cp++ = '\0';
1162 if (dstlen != 0)
1163 {
1165 cp += dstlen;
1166 *cp = '\0';
1167 }
1168 return true;
1169}
return str start
#define TZDEFRULESTRING
Definition localtime.c:67
static ATTRIBUTE_PURE_114833 const char * getzname(const char *strp)
Definition localtime.c:651
static int_fast32_t transtime(const int year, const struct rule *const rulep, const int_fast32_t offset)
Definition localtime.c:850
static bool increment_overflow(int *ip, int j)
Definition localtime.c:1511
static ATTRIBUTE_PURE_114833 const char * getqzname(const char *strp, const int delim)
Definition localtime.c:672
static void init_ttinfo(struct ttinfo *s, int_fast32_t utoff, bool isdst, desigidx_type desigidx)
Definition localtime.c:152
static const char * getrule(const char *strp, struct rule *const rulep)
Definition localtime.c:789
#define TZNAME_MAXIMUM
Definition pgtz.h:37
@ years_of_observations
Definition private.h:241

References charcnt, EPOCH_YEAR, fb(), getoffset(), getqzname(), getrule(), getzname(), i, increment_overflow(), increment_overflow_time(), init_ttinfo(), isleap, leapcount(), lsinfo::ls_trans, memcpy(), name, SECSPERDAY, SECSPERHOUR, set_leapcount(), set_lsinfo(), start, TIME_T_MIN, timecnt, transtime(), TZ_MAX_TIMES, TZDEFRULESTRING, TZNAME_MAXIMUM, year_lengths, years_of_observations, and YEARSPERREPEAT.

Referenced by gmtload(), pg_tzload(), and tzloadbody().

Variable Documentation

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

628 {
629 {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
630 {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
631};

Referenced by timesub(), and transtime().

◆ tm

struct pg_tm tm
static

Definition at line 148 of file localtime.c.

Referenced by abstime2tm(), AdjustFractDays(), AdjustFractSeconds(), AppendTimestampSeconds(), build_time_t(), cache_locale_time(), check_recovery_target_time(), ClearPgTm(), createBackupLabel(), date2timestamptz_safe(), date_in(), date_out(), DCH_to_char(), DecodeDate(), DecodeDate(), DecodeDateTime(), DecodeDateTime(), DecodeInterval(), DecodeISO8601Interval(), DecodeNumber(), DecodeNumber(), DecodeNumberField(), DecodeNumberField(), DecodeTime(), DecodeTime(), DecodeTimeOnly(), DetermineTimeZoneAbbrevOffset(), DetermineTimeZoneAbbrevOffsetTS(), DetermineTimeZoneOffset(), DetermineTimeZoneOffsetInternal(), do_to_timestamp(), dttofmtasc_replace(), EncodeDateOnly(), EncodeDateOnly(), EncodeDateTime(), EncodeDateTime(), EncodeInterval(), EncodeTimeOnly(), executeDateTimeMethod(), gbt_num_compress(), get_timezone_offset(), GetCurrentDateTime(), GetCurrentDateTime(), GetCurrentTimeUsec(), GetEpochTime(), GetEpochTime(), GetSQLCurrentDate(), GetSQLCurrentTime(), GetSQLLocalTime(), identify_system_timezone(), interval2tm(), interval_part_common(), interval_to_char(), interval_trunc(), JsonEncodeDateTime(), llvm_create_jit_instance(), locale_date_order(), main(), make_date(), make_output_dirs(), make_timestamp_internal(), map_sql_value_to_xml_value(), my_strftime(), parse_datetime(), parse_sane_timezone(), pg_get_role_ddl_internal(), pg_gmtime(), pg_localtime(), pg_timezone_names(), 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(), pqTraceFormatTimestamp(), ReadHead(), score_timezone(), set_next_rotation_time(), SetEpochTimestamp(), SetEpochTimestamp(), tarOpen(), time2tm(), time_in(), time_out(), time_part_common(), time_t_to_timestamptz(), time_timetz(), timeofday(), timestamp2date_safe(), timestamp2timestamptz_safe(), timestamp2tm(), timestamp2tm(), timestamp_age(), timestamp_in(), timestamp_out(), timestamp_part_common(), timestamp_pl_interval(), timestamp_recv(), timestamp_time(), timestamp_to_char(), timestamp_trunc(), timestamp_zone(), timestamptz2date_safe(), timestamptz2timestamp_safe(), timestamptz_age(), 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(), tm2timestamp(), tm2timetz(), to_date(), to_timestamp(), typenameTypeMod(), ValidateDate(), WriteHead(), and writezone().

◆ wildabbr

const char wildabbr[] = WILDABBR
static

Definition at line 58 of file localtime.c.

Referenced by gmtsub().

◆ year_lengths

const int year_lengths[2]
static
Initial value:

Definition at line 633 of file localtime.c.

633 {
635};

Referenced by timesub(), and tzparse().