PostgreSQL Source Code git master
Loading...
Searching...
No Matches
pgtime.h File Reference
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  pg_tm
 

Macros

#define TZ_STRLEN_MAX   255
 

Typedefs

typedef int64 pg_time_t
 
typedef struct pg_tz pg_tz
 
typedef struct pg_tzenum pg_tzenum
 

Functions

struct pg_tmpg_localtime (const pg_time_t *timep, const pg_tz *tz)
 
struct pg_tmpg_gmtime (const pg_time_t *timep)
 
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)
 
size_t pg_strftime (char *s, size_t maxsize, const char *format, const struct pg_tm *t)
 
void pg_timezone_initialize (void)
 
pg_tzpg_tzset (const char *tzname)
 
pg_tzpg_tzset_offset (long gmtoffset)
 
pg_tzenumpg_tzenumerate_start (void)
 
pg_tzpg_tzenumerate_next (pg_tzenum *dir)
 
void pg_tzenumerate_end (pg_tzenum *dir)
 

Variables

PGDLLIMPORT pg_tzsession_timezone
 
PGDLLIMPORT pg_tzlog_timezone
 

Macro Definition Documentation

◆ TZ_STRLEN_MAX

#define TZ_STRLEN_MAX   255

Definition at line 54 of file pgtime.h.

Typedef Documentation

◆ pg_time_t

Definition at line 23 of file pgtime.h.

◆ pg_tz

Definition at line 50 of file pgtime.h.

◆ pg_tzenum

Definition at line 51 of file pgtime.h.

Function Documentation

◆ pg_get_next_timezone_abbrev()

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

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}
uint32 result
static int fb(int x)
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)
extern

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 
)
extern

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}
int i
Definition isn.c:77
struct ttinfo ttis[TZ_MAX_TYPES]
Definition pgtz.h:95
int_least32_t tt_utoff
Definition pgtz.h:49

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)
extern

Definition at line 1333 of file localtime.c.

1334{
1335 return gmtsub(timep, 0, &tm);
1336}
static struct pg_tm * gmtsub(pg_time_t const *timep, int_fast32_t offset, struct pg_tm *tmp)
Definition localtime.c:1302
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 
)
extern

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}
int64 pg_time_t
Definition pgtime.h:23
Definition pgtz.h:48
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()

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

Definition at line 1289 of file localtime.c.

1290{
1291 return localsub(&tz->state, timep, &tm);
1292}
static struct pg_tm * localsub(struct state const *sp, pg_time_t const *timep, struct pg_tm *const tmp)
Definition localtime.c:1186

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

Referenced by build_backup_content(), get_formatted_log_time(), get_formatted_start_time(), log_status_format(), logfile_getname(), pg_tz_acceptable(), score_timezone(), set_next_rotation_time(), str_time(), timeofday(), and timestamp2tm().

◆ 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 
)
extern

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 j
Definition isn.c:78
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
#define AVGSECSPERYEAR
Definition private.h:224
@ YEARSPERREPEAT
Definition private.h:217

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_strftime()

size_t pg_strftime ( char s,
size_t  maxsize,
const char format,
const struct pg_tm t 
)
extern

Definition at line 129 of file strftime.c.

130{
131 char *p;
132 int saved_errno = errno;
133 enum warn warn = IN_NONE;
134
135 p = _fmt(format, t, s, s + maxsize, &warn);
136 if (!p)
137 {
139 if (maxsize > 0)
140 *s = '\0';
141 return 0;
142 }
143 if (p == s + maxsize)
144 {
145 errno = ERANGE;
146 if (maxsize > 0)
147 *s = '\0';
148 return 0;
149 }
150 *p = '\0';
151 errno = saved_errno;
152 return p - s;
153}
static char format
#define EOVERFLOW
Definition private.h:88
warn
Definition strftime.c:104
@ IN_NONE
Definition strftime.c:105
static char * _fmt(const char *format, const struct pg_tm *t, char *pt, const char *ptlim, enum warn *warnp)
Definition strftime.c:156

References _fmt(), EOVERFLOW, fb(), format, and IN_NONE.

Referenced by AddFileToBackupManifest(), build_backup_content(), get_formatted_log_time(), get_formatted_start_time(), log_status_format(), logfile_getname(), str_time(), and timeofday().

◆ 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 
)
extern

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_timezone_initialize()

void pg_timezone_initialize ( void  )
extern

Definition at line 341 of file pgtz.c.

342{
343 /*
344 * We may not yet know where PGSHAREDIR is (in particular this is true in
345 * an EXEC_BACKEND subprocess). So use "GMT", which pg_tzset forces to be
346 * interpreted without reference to the filesystem. This corresponds to
347 * the bootstrap default for these variables in guc_parameters.dat,
348 * although in principle it could be different.
349 */
350 session_timezone = pg_tzset("GMT");
352}
pg_tz * log_timezone
Definition pgtz.c:31
pg_tz * pg_tzset(const char *tzname)
Definition pgtz.c:224
pg_tz * session_timezone
Definition pgtz.c:28

References log_timezone, pg_tzset(), and session_timezone.

Referenced by InitializeGUCOptions().

◆ pg_tz_acceptable()

bool pg_tz_acceptable ( pg_tz tz)
extern

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
Definition pgtime.h:35

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_tzenumerate_end()

void pg_tzenumerate_end ( pg_tzenum dir)
extern

Definition at line 394 of file pgtz.c.

395{
396 while (dir->depth >= 0)
397 {
398 FreeDir(dir->dirdesc[dir->depth]);
399 pfree(dir->dirname[dir->depth]);
400 dir->depth--;
401 }
402 pfree(dir);
403}
int FreeDir(DIR *dir)
Definition fd.c:3009
void pfree(void *pointer)
Definition mcxt.c:1619
char * dirname[MAX_TZDIR_DEPTH]
Definition pgtz.c:370
int depth
Definition pgtz.c:368
DIR * dirdesc[MAX_TZDIR_DEPTH]
Definition pgtz.c:369

References pg_tzenum::depth, pg_tzenum::dirdesc, pg_tzenum::dirname, FreeDir(), and pfree().

Referenced by pg_timezone_names().

◆ pg_tzenumerate_next()

pg_tz * pg_tzenumerate_next ( pg_tzenum dir)
extern

Definition at line 406 of file pgtz.c.

407{
408 while (dir->depth >= 0)
409 {
410 struct dirent *direntry;
411 char fullname[MAXPGPATH * 2];
412
413 direntry = ReadDir(dir->dirdesc[dir->depth], dir->dirname[dir->depth]);
414
415 if (!direntry)
416 {
417 /* End of this directory */
418 FreeDir(dir->dirdesc[dir->depth]);
419 pfree(dir->dirname[dir->depth]);
420 dir->depth--;
421 continue;
422 }
423
424 if (direntry->d_name[0] == '.')
425 continue;
426
427 snprintf(fullname, sizeof(fullname), "%s/%s",
428 dir->dirname[dir->depth], direntry->d_name);
429
431 {
432 /* Step into the subdirectory */
433 if (dir->depth >= MAX_TZDIR_DEPTH - 1)
435 (errmsg_internal("timezone directory stack overflow")));
436 dir->depth++;
437 dir->dirname[dir->depth] = pstrdup(fullname);
438 dir->dirdesc[dir->depth] = AllocateDir(fullname);
439 if (!dir->dirdesc[dir->depth])
442 errmsg("could not open directory \"%s\": %m",
443 fullname)));
444
445 /* Start over reading in the new directory */
446 continue;
447 }
448
449 /*
450 * Load this timezone using pg_tzload() not pg_tzset(), so we don't
451 * fill the cache. Also, don't ask for the canonical spelling: we
452 * already know it, and pg_open_tzfile's way of finding it out is
453 * pretty inefficient.
454 */
455 if (!pg_tzload(fullname + dir->baselen, NULL, &dir->tz.state))
456 {
457 /* Zone could not be loaded, ignore it */
458 continue;
459 }
460
461 if (!pg_tz_acceptable(&dir->tz))
462 {
463 /* Ignore leap-second zones */
464 continue;
465 }
466
467 /* OK, return the canonical zone name spelling. */
468 strlcpy(dir->tz.TZname, fullname + dir->baselen,
469 sizeof(dir->tz.TZname));
470
471 /* Timezone loaded OK. */
472 return &dir->tz;
473 }
474
475 /* Nothing more found */
476 return NULL;
477}
int errcode_for_file_access(void)
Definition elog.c:898
int int errmsg_internal(const char *fmt,...) pg_attribute_printf(1
#define ERROR
Definition elog.h:40
#define ereport(elevel,...)
Definition elog.h:152
DIR * AllocateDir(const char *dirname)
Definition fd.c:2891
struct dirent * ReadDir(DIR *dir, const char *dirname)
Definition fd.c:2957
PGFileType get_dirent_type(const char *path, const struct dirent *de, bool look_through_symlinks, int elevel)
Definition file_utils.c:547
@ PGFILETYPE_DIR
Definition file_utils.h:23
bool pg_tzload(const char *name, char *canonname, struct state *sp)
Definition localtime.c:1590
char * pstrdup(const char *in)
Definition mcxt.c:1910
static char * errmsg
#define MAXPGPATH
bool pg_tz_acceptable(pg_tz *tz)
Definition localtime.c:2028
#define MAX_TZDIR_DEPTH
Definition pgtz.c:363
#define snprintf
Definition port.h:261
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition strlcpy.c:45
int baselen
Definition pgtz.c:367
struct pg_tz tz
Definition pgtz.c:371

References AllocateDir(), pg_tzenum::baselen, pg_tzenum::depth, pg_tzenum::dirdesc, pg_tzenum::dirname, ereport, errcode_for_file_access(), errmsg, errmsg_internal(), ERROR, fb(), FreeDir(), get_dirent_type(), MAX_TZDIR_DEPTH, MAXPGPATH, pfree(), pg_tz_acceptable(), pg_tzload(), PGFILETYPE_DIR, pstrdup(), ReadDir(), snprintf, pg_tz::state, strlcpy(), pg_tzenum::tz, and pg_tz::TZname.

Referenced by pg_timezone_names().

◆ pg_tzenumerate_start()

pg_tzenum * pg_tzenumerate_start ( void  )
extern

Definition at line 377 of file pgtz.c.

378{
380 char *startdir = pstrdup(pg_TZDIR());
381
382 ret->baselen = strlen(startdir) + 1;
383 ret->depth = 0;
384 ret->dirname[0] = startdir;
385 ret->dirdesc[0] = AllocateDir(startdir);
386 if (!ret->dirdesc[0])
389 errmsg("could not open directory \"%s\": %m", startdir)));
390 return ret;
391}
#define palloc0_object(type)
Definition fe_memutils.h:90
static const char * pg_TZDIR(void)
Definition pgtz.c:43

References AllocateDir(), pg_tzenum::baselen, pg_tzenum::depth, pg_tzenum::dirdesc, pg_tzenum::dirname, ereport, errcode_for_file_access(), errmsg, ERROR, fb(), palloc0_object, pg_TZDIR(), and pstrdup().

Referenced by pg_timezone_names().

◆ pg_tzset()

pg_tz * pg_tzset ( const char tzname)
extern

Definition at line 224 of file pgtz.c.

225{
226 pg_tz_cache *tzp;
227 struct state tzstate;
228 char uppername[TZ_STRLEN_MAX + 1];
229 char canonname[TZ_STRLEN_MAX + 1];
230 char *p;
231
233 return NULL; /* not going to fit */
234
235 if (!timezone_cache)
237 return NULL;
238
239 /*
240 * Upcase the given name to perform a case-insensitive hashtable search.
241 * (We could alternatively downcase it, but we prefer upcase so that we
242 * can get consistently upcased results from pg_tzload() in case the name
243 * is a POSIX-style timezone spec.)
244 */
245 p = uppername;
246 while (*tzname)
247 *p++ = pg_toupper((unsigned char) *tzname++);
248 *p = '\0';
249
251 uppername,
252 HASH_FIND,
253 NULL);
254 if (tzp)
255 {
256 /* Timezone found in cache, nothing more to do */
257 return &tzp->tz;
258 }
259
260 /*
261 * Let the IANA tzdb code interpret the time zone name.
262 */
264 {
265 if (strcmp(uppername, "GMT") == 0)
266 {
267 /* This really, really should not happen ... */
268 elog(ERROR, "could not initialize GMT time zone");
269 }
270 /* Unknown timezone. Fail our call instead of loading GMT! */
271 return NULL;
272 }
273
274 /* Save timezone in the cache */
276 uppername,
278 NULL);
279
280 /* hash_search already copied uppername into the hash key */
281 strcpy(tzp->tz.TZname, canonname);
282 memcpy(&tzp->tz.state, &tzstate, sizeof(tzstate));
283
284 return &tzp->tz;
285}
memcpy(sums, checksumBaseOffsets, sizeof(checksumBaseOffsets))
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
Definition dynahash.c:889
#define elog(elevel,...)
Definition elog.h:228
@ HASH_FIND
Definition hsearch.h:108
@ HASH_ENTER
Definition hsearch.h:109
#define TZ_STRLEN_MAX
Definition pgtime.h:54
static HTAB * timezone_cache
Definition pgtz.c:198
static bool init_timezone_hashtable(void)
Definition pgtz.c:202
unsigned char pg_toupper(unsigned char ch)
pg_tz tz
Definition pgtz.c:195

References elog, ERROR, fb(), HASH_ENTER, HASH_FIND, hash_search(), init_timezone_hashtable(), memcpy(), pg_toupper(), pg_tzload(), pg_tz::state, timezone_cache, pg_tz_cache::tz, TZ_STRLEN_MAX, and pg_tz::TZname.

Referenced by check_log_timezone(), check_timezone(), DecodeDateTime(), DecodeTimeOnly(), DecodeTimezoneName(), FetchDynamicTimeZone(), pg_timezone_initialize(), and pg_tzset_offset().

◆ pg_tzset_offset()

pg_tz * pg_tzset_offset ( long  gmtoffset)
extern

Definition at line 300 of file pgtz.c.

301{
302 long absoffset = (gmtoffset < 0) ? -gmtoffset : gmtoffset;
303 char offsetstr[64];
304 char tzname[128];
305
307 "%02ld", absoffset / SECS_PER_HOUR);
309 if (absoffset != 0)
310 {
312 sizeof(offsetstr) - strlen(offsetstr),
313 ":%02ld", absoffset / SECS_PER_MINUTE);
315 if (absoffset != 0)
317 sizeof(offsetstr) - strlen(offsetstr),
318 ":%02ld", absoffset);
319 }
320 if (gmtoffset > 0)
321 snprintf(tzname, sizeof(tzname), "<-%s>+%s",
323 else
324 snprintf(tzname, sizeof(tzname), "<+%s>-%s",
326
327 return pg_tzset(tzname);
328}
#define SECS_PER_HOUR
Definition timestamp.h:127
#define SECS_PER_MINUTE
Definition timestamp.h:128

References fb(), pg_tzset(), SECS_PER_HOUR, SECS_PER_MINUTE, and snprintf.

Referenced by check_timezone(), and DecodeTimezoneNameToTz().

Variable Documentation

◆ log_timezone

◆ session_timezone