PostgreSQL Source Code  git master
dt.h File Reference
Include dependency graph for dt.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  datetkn
 

Macros

#define MAXTZLEN   10
 
#define USE_POSTGRES_DATES   0
 
#define USE_ISO_DATES   1
 
#define USE_SQL_DATES   2
 
#define USE_GERMAN_DATES   3
 
#define INTSTYLE_POSTGRES   0
 
#define INTSTYLE_POSTGRES_VERBOSE   1
 
#define INTSTYLE_SQL_STANDARD   2
 
#define INTSTYLE_ISO_8601   3
 
#define INTERVAL_FULL_RANGE   (0x7FFF)
 
#define INTERVAL_MASK(b)   (1 << (b))
 
#define MAX_INTERVAL_PRECISION   6
 
#define DTERR_BAD_FORMAT   (-1)
 
#define DTERR_FIELD_OVERFLOW   (-2)
 
#define DTERR_MD_FIELD_OVERFLOW   (-3) /* triggers hint about DateStyle */
 
#define DTERR_INTERVAL_OVERFLOW   (-4)
 
#define DTERR_TZDISP_OVERFLOW   (-5)
 
#define DAGO   "ago"
 
#define DCURRENT   "current"
 
#define EPOCH   "epoch"
 
#define INVALID   "invalid"
 
#define EARLY   "-infinity"
 
#define LATE   "infinity"
 
#define NOW   "now"
 
#define TODAY   "today"
 
#define TOMORROW   "tomorrow"
 
#define YESTERDAY   "yesterday"
 
#define ZULU   "zulu"
 
#define DMICROSEC   "usecond"
 
#define DMILLISEC   "msecond"
 
#define DSECOND   "second"
 
#define DMINUTE   "minute"
 
#define DHOUR   "hour"
 
#define DDAY   "day"
 
#define DWEEK   "week"
 
#define DMONTH   "month"
 
#define DQUARTER   "quarter"
 
#define DYEAR   "year"
 
#define DDECADE   "decade"
 
#define DCENTURY   "century"
 
#define DMILLENNIUM   "millennium"
 
#define DA_D   "ad"
 
#define DB_C   "bc"
 
#define DTIMEZONE   "timezone"
 
#define AM   0
 
#define PM   1
 
#define HR24   2
 
#define AD   0
 
#define BC   1
 
#define RESERV   0
 
#define MONTH   1
 
#define YEAR   2
 
#define DAY   3
 
#define JULIAN   4
 
#define TZ   5 /* fixed-offset timezone abbreviation */
 
#define DTZ   6 /* fixed-offset timezone abbrev, DST */
 
#define DYNTZ   7 /* dynamic timezone abbr (unimplemented) */
 
#define IGNORE_DTF   8
 
#define AMPM   9
 
#define HOUR   10
 
#define MINUTE   11
 
#define SECOND   12
 
#define MILLISECOND   13
 
#define MICROSECOND   14
 
#define DOY   15
 
#define DOW   16
 
#define UNITS   17
 
#define ADBC   18
 
#define AGO   19
 
#define ABS_BEFORE   20
 
#define ABS_AFTER   21
 
#define ISODATE   22
 
#define ISOTIME   23
 
#define DTZMOD   28 /* "DST" as a separate word */
 
#define UNKNOWN_FIELD   31
 
#define DTK_NUMBER   0
 
#define DTK_STRING   1
 
#define DTK_DATE   2
 
#define DTK_TIME   3
 
#define DTK_TZ   4
 
#define DTK_AGO   5
 
#define DTK_SPECIAL   6
 
#define DTK_INVALID   7
 
#define DTK_CURRENT   8
 
#define DTK_EARLY   9
 
#define DTK_LATE   10
 
#define DTK_EPOCH   11
 
#define DTK_NOW   12
 
#define DTK_YESTERDAY   13
 
#define DTK_TODAY   14
 
#define DTK_TOMORROW   15
 
#define DTK_ZULU   16
 
#define DTK_DELTA   17
 
#define DTK_SECOND   18
 
#define DTK_MINUTE   19
 
#define DTK_HOUR   20
 
#define DTK_DAY   21
 
#define DTK_WEEK   22
 
#define DTK_MONTH   23
 
#define DTK_QUARTER   24
 
#define DTK_YEAR   25
 
#define DTK_DECADE   26
 
#define DTK_CENTURY   27
 
#define DTK_MILLENNIUM   28
 
#define DTK_MILLISEC   29
 
#define DTK_MICROSEC   30
 
#define DTK_JULIAN   31
 
#define DTK_DOW   32
 
#define DTK_DOY   33
 
#define DTK_TZ_HOUR   34
 
#define DTK_TZ_MINUTE   35
 
#define DTK_ISOYEAR   36
 
#define DTK_ISODOW   37
 
#define DTK_M(t)   (0x01 << (t))
 
#define DTK_ALL_SECS_M   (DTK_M(SECOND) | DTK_M(MILLISECOND) | DTK_M(MICROSECOND))
 
#define DTK_DATE_M   (DTK_M(YEAR) | DTK_M(MONTH) | DTK_M(DAY))
 
#define DTK_TIME_M   (DTK_M(HOUR) | DTK_M(MINUTE) | DTK_M(SECOND))
 
#define MAXDATELEN   128
 
#define MAXDATEFIELDS   25
 
#define TOKMAXLEN   10
 
#define FMODULO(t, q, u)
 
#define TMODULO(t, q, u)
 
#define DAYS_PER_YEAR   365.25 /* assumes leap year every four years */
 
#define MONTHS_PER_YEAR   12
 
#define DAYS_PER_MONTH   30 /* assumes exactly 30 days per month */
 
#define HOURS_PER_DAY   24 /* assume no daylight savings time changes */
 
#define SECS_PER_YEAR   (36525 * 864) /* avoid floating-point computation */
 
#define SECS_PER_DAY   86400
 
#define SECS_PER_HOUR   3600
 
#define SECS_PER_MINUTE   60
 
#define MINS_PER_HOUR   60
 
#define USECS_PER_DAY   INT64CONST(86400000000)
 
#define USECS_PER_HOUR   INT64CONST(3600000000)
 
#define USECS_PER_MINUTE   INT64CONST(60000000)
 
#define USECS_PER_SEC   INT64CONST(1000000)
 
#define isleap(y)   (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
 
#define JULIAN_MINYEAR   (-4713)
 
#define JULIAN_MINMONTH   (11)
 
#define JULIAN_MINDAY   (24)
 
#define JULIAN_MAXYEAR   (5874898)
 
#define JULIAN_MAXMONTH   (6)
 
#define JULIAN_MAXDAY   (3)
 
#define IS_VALID_JULIAN(y, m, d)
 
#define MIN_TIMESTAMP   INT64CONST(-211813488000000000)
 
#define END_TIMESTAMP   INT64CONST(9223371331200000000)
 
#define IS_VALID_TIMESTAMP(t)   (MIN_TIMESTAMP <= (t) && (t) < END_TIMESTAMP)
 
#define UTIME_MINYEAR   (1901)
 
#define UTIME_MINMONTH   (12)
 
#define UTIME_MINDAY   (14)
 
#define UTIME_MAXYEAR   (2038)
 
#define UTIME_MAXMONTH   (01)
 
#define UTIME_MAXDAY   (18)
 
#define IS_VALID_UTIME(y, m, d)
 
#define DT_NOBEGIN   (-INT64CONST(0x7fffffffffffffff) - 1)
 
#define DT_NOEND   (INT64CONST(0x7fffffffffffffff))
 
#define TIMESTAMP_NOBEGIN(j)   do {(j) = DT_NOBEGIN;} while (0)
 
#define TIMESTAMP_NOEND(j)   do {(j) = DT_NOEND;} while (0)
 
#define TIMESTAMP_IS_NOBEGIN(j)   ((j) == DT_NOBEGIN)
 
#define TIMESTAMP_IS_NOEND(j)   ((j) == DT_NOEND)
 
#define TIMESTAMP_NOT_FINITE(j)   (TIMESTAMP_IS_NOBEGIN(j) || TIMESTAMP_IS_NOEND(j))
 

Typedefs

typedef int32 fsec_t
 

Functions

int DecodeInterval (char **, int *, int, int *, struct tm *, fsec_t *)
 
int DecodeTime (char *, int *, struct tm *, fsec_t *)
 
void EncodeDateTime (struct tm *tm, fsec_t fsec, bool print_tz, int tz, const char *tzn, int style, char *str, bool EuroDates)
 
void EncodeInterval (struct tm *tm, fsec_t fsec, int style, char *str)
 
int tm2timestamp (struct tm *, fsec_t, int *, timestamp *)
 
int DecodeUnits (int field, char *lowtoken, int *val)
 
bool CheckDateTokenTables (void)
 
void EncodeDateOnly (struct tm *tm, int style, char *str, bool EuroDates)
 
int GetEpochTime (struct tm *)
 
int ParseDateTime (char *, char *, char **, int *, int *, char **)
 
int DecodeDateTime (char **, int *, int, int *, struct tm *, fsec_t *, bool)
 
void j2date (int, int *, int *, int *)
 
void GetCurrentDateTime (struct tm *)
 
int date2j (int, int, int)
 
void TrimTrailingZeros (char *)
 
void dt2time (double, int *, int *, int *, fsec_t *)
 
int PGTYPEStimestamp_defmt_scan (char **str, char *fmt, timestamp *d, int *year, int *month, int *day, int *hour, int *minute, int *second, int *tz)
 

Variables

char * pgtypes_date_weekdays_short []
 
char * pgtypes_date_months []
 
char * months []
 
char * days []
 
int day_tab [2][13]
 

Macro Definition Documentation

◆ ABS_AFTER

#define ABS_AFTER   21

Definition at line 112 of file dt.h.

◆ ABS_BEFORE

#define ABS_BEFORE   20

Definition at line 111 of file dt.h.

◆ AD

#define AD   0

Definition at line 73 of file dt.h.

◆ ADBC

#define ADBC   18

Definition at line 108 of file dt.h.

◆ AGO

#define AGO   19

Definition at line 110 of file dt.h.

◆ AM

#define AM   0

Definition at line 69 of file dt.h.

◆ AMPM

#define AMPM   9

Definition at line 99 of file dt.h.

◆ BC

#define BC   1

Definition at line 74 of file dt.h.

◆ DA_D

#define DA_D   "ad"

Definition at line 58 of file dt.h.

◆ DAGO

#define DAGO   "ago"

Definition at line 33 of file dt.h.

◆ DAY

#define DAY   3

Definition at line 93 of file dt.h.

◆ DAYS_PER_MONTH

#define DAYS_PER_MONTH   30 /* assumes exactly 30 days per month */

Definition at line 244 of file dt.h.

◆ DAYS_PER_YEAR

#define DAYS_PER_YEAR   365.25 /* assumes leap year every four years */

Definition at line 235 of file dt.h.

◆ DB_C

#define DB_C   "bc"

Definition at line 59 of file dt.h.

◆ DCENTURY

#define DCENTURY   "century"

Definition at line 56 of file dt.h.

◆ DCURRENT

#define DCURRENT   "current"

Definition at line 34 of file dt.h.

◆ DDAY

#define DDAY   "day"

Definition at line 50 of file dt.h.

◆ DDECADE

#define DDECADE   "decade"

Definition at line 55 of file dt.h.

◆ DHOUR

#define DHOUR   "hour"

Definition at line 49 of file dt.h.

◆ DMICROSEC

#define DMICROSEC   "usecond"

Definition at line 45 of file dt.h.

◆ DMILLENNIUM

#define DMILLENNIUM   "millennium"

Definition at line 57 of file dt.h.

◆ DMILLISEC

#define DMILLISEC   "msecond"

Definition at line 46 of file dt.h.

◆ DMINUTE

#define DMINUTE   "minute"

Definition at line 48 of file dt.h.

◆ DMONTH

#define DMONTH   "month"

Definition at line 52 of file dt.h.

◆ DOW

#define DOW   16

Definition at line 106 of file dt.h.

◆ DOY

#define DOY   15

Definition at line 105 of file dt.h.

◆ DQUARTER

#define DQUARTER   "quarter"

Definition at line 53 of file dt.h.

◆ DSECOND

#define DSECOND   "second"

Definition at line 47 of file dt.h.

◆ DT_NOBEGIN

#define DT_NOBEGIN   (-INT64CONST(0x7fffffffffffffff) - 1)

Definition at line 305 of file dt.h.

◆ DT_NOEND

#define DT_NOEND   (INT64CONST(0x7fffffffffffffff))

Definition at line 306 of file dt.h.

◆ DTERR_BAD_FORMAT

#define DTERR_BAD_FORMAT   (-1)

Definition at line 26 of file dt.h.

◆ DTERR_FIELD_OVERFLOW

#define DTERR_FIELD_OVERFLOW   (-2)

Definition at line 27 of file dt.h.

◆ DTERR_INTERVAL_OVERFLOW

#define DTERR_INTERVAL_OVERFLOW   (-4)

Definition at line 29 of file dt.h.

◆ DTERR_MD_FIELD_OVERFLOW

#define DTERR_MD_FIELD_OVERFLOW   (-3) /* triggers hint about DateStyle */

Definition at line 28 of file dt.h.

◆ DTERR_TZDISP_OVERFLOW

#define DTERR_TZDISP_OVERFLOW   (-5)

Definition at line 30 of file dt.h.

◆ DTIMEZONE

#define DTIMEZONE   "timezone"

Definition at line 60 of file dt.h.

◆ DTK_AGO

#define DTK_AGO   5

Definition at line 143 of file dt.h.

◆ DTK_ALL_SECS_M

#define DTK_ALL_SECS_M   (DTK_M(SECOND) | DTK_M(MILLISECOND) | DTK_M(MICROSECOND))

Definition at line 186 of file dt.h.

◆ DTK_CENTURY

#define DTK_CENTURY   27

Definition at line 167 of file dt.h.

◆ DTK_CURRENT

#define DTK_CURRENT   8

Definition at line 147 of file dt.h.

◆ DTK_DATE

#define DTK_DATE   2

Definition at line 140 of file dt.h.

◆ DTK_DATE_M

#define DTK_DATE_M   (DTK_M(YEAR) | DTK_M(MONTH) | DTK_M(DAY))

Definition at line 187 of file dt.h.

◆ DTK_DAY

#define DTK_DAY   21

Definition at line 161 of file dt.h.

◆ DTK_DECADE

#define DTK_DECADE   26

Definition at line 166 of file dt.h.

◆ DTK_DELTA

#define DTK_DELTA   17

Definition at line 157 of file dt.h.

◆ DTK_DOW

#define DTK_DOW   32

Definition at line 173 of file dt.h.

◆ DTK_DOY

#define DTK_DOY   33

Definition at line 174 of file dt.h.

◆ DTK_EARLY

#define DTK_EARLY   9

Definition at line 148 of file dt.h.

◆ DTK_EPOCH

#define DTK_EPOCH   11

Definition at line 150 of file dt.h.

◆ DTK_HOUR

#define DTK_HOUR   20

Definition at line 160 of file dt.h.

◆ DTK_INVALID

#define DTK_INVALID   7

Definition at line 146 of file dt.h.

◆ DTK_ISODOW

#define DTK_ISODOW   37

Definition at line 178 of file dt.h.

◆ DTK_ISOYEAR

#define DTK_ISOYEAR   36

Definition at line 177 of file dt.h.

◆ DTK_JULIAN

#define DTK_JULIAN   31

Definition at line 171 of file dt.h.

◆ DTK_LATE

#define DTK_LATE   10

Definition at line 149 of file dt.h.

◆ DTK_M

#define DTK_M (   t)    (0x01 << (t))

Definition at line 185 of file dt.h.

◆ DTK_MICROSEC

#define DTK_MICROSEC   30

Definition at line 170 of file dt.h.

◆ DTK_MILLENNIUM

#define DTK_MILLENNIUM   28

Definition at line 168 of file dt.h.

◆ DTK_MILLISEC

#define DTK_MILLISEC   29

Definition at line 169 of file dt.h.

◆ DTK_MINUTE

#define DTK_MINUTE   19

Definition at line 159 of file dt.h.

◆ DTK_MONTH

#define DTK_MONTH   23

Definition at line 163 of file dt.h.

◆ DTK_NOW

#define DTK_NOW   12

Definition at line 151 of file dt.h.

◆ DTK_NUMBER

#define DTK_NUMBER   0

Definition at line 137 of file dt.h.

◆ DTK_QUARTER

#define DTK_QUARTER   24

Definition at line 164 of file dt.h.

◆ DTK_SECOND

#define DTK_SECOND   18

Definition at line 158 of file dt.h.

◆ DTK_SPECIAL

#define DTK_SPECIAL   6

Definition at line 145 of file dt.h.

◆ DTK_STRING

#define DTK_STRING   1

Definition at line 138 of file dt.h.

◆ DTK_TIME

#define DTK_TIME   3

Definition at line 141 of file dt.h.

◆ DTK_TIME_M

#define DTK_TIME_M   (DTK_M(HOUR) | DTK_M(MINUTE) | DTK_M(SECOND))

Definition at line 188 of file dt.h.

◆ DTK_TODAY

#define DTK_TODAY   14

Definition at line 153 of file dt.h.

◆ DTK_TOMORROW

#define DTK_TOMORROW   15

Definition at line 154 of file dt.h.

◆ DTK_TZ

#define DTK_TZ   4

Definition at line 142 of file dt.h.

◆ DTK_TZ_HOUR

#define DTK_TZ_HOUR   34

Definition at line 175 of file dt.h.

◆ DTK_TZ_MINUTE

#define DTK_TZ_MINUTE   35

Definition at line 176 of file dt.h.

◆ DTK_WEEK

#define DTK_WEEK   22

Definition at line 162 of file dt.h.

◆ DTK_YEAR

#define DTK_YEAR   25

Definition at line 165 of file dt.h.

◆ DTK_YESTERDAY

#define DTK_YESTERDAY   13

Definition at line 152 of file dt.h.

◆ DTK_ZULU

#define DTK_ZULU   16

Definition at line 155 of file dt.h.

◆ DTZ

#define DTZ   6 /* fixed-offset timezone abbrev, DST */

Definition at line 96 of file dt.h.

◆ DTZMOD

#define DTZMOD   28 /* "DST" as a separate word */

Definition at line 117 of file dt.h.

◆ DWEEK

#define DWEEK   "week"

Definition at line 51 of file dt.h.

◆ DYEAR

#define DYEAR   "year"

Definition at line 54 of file dt.h.

◆ DYNTZ

#define DYNTZ   7 /* dynamic timezone abbr (unimplemented) */

Definition at line 97 of file dt.h.

◆ EARLY

#define EARLY   "-infinity"

Definition at line 37 of file dt.h.

◆ END_TIMESTAMP

#define END_TIMESTAMP   INT64CONST(9223371331200000000)

Definition at line 287 of file dt.h.

◆ EPOCH

#define EPOCH   "epoch"

Definition at line 35 of file dt.h.

◆ FMODULO

#define FMODULO (   t,
  q,
 
)
Value:
do { \
(q) = (((t) < 0) ? ceil((t) / (u)): floor((t) / (u))); \
if ((q) != 0) (t) -= rint((q) * (u)); \
} while(0)
double rint(double x)
Definition: rint.c:22

Definition at line 217 of file dt.h.

◆ HOUR

#define HOUR   10

Definition at line 100 of file dt.h.

◆ HOURS_PER_DAY

#define HOURS_PER_DAY   24 /* assume no daylight savings time changes */

Definition at line 245 of file dt.h.

◆ HR24

#define HR24   2

Definition at line 71 of file dt.h.

◆ IGNORE_DTF

#define IGNORE_DTF   8

Definition at line 98 of file dt.h.

◆ INTERVAL_FULL_RANGE

#define INTERVAL_FULL_RANGE   (0x7FFF)

Definition at line 22 of file dt.h.

◆ INTERVAL_MASK

#define INTERVAL_MASK (   b)    (1 << (b))

Definition at line 23 of file dt.h.

◆ INTSTYLE_ISO_8601

#define INTSTYLE_ISO_8601   3

Definition at line 20 of file dt.h.

◆ INTSTYLE_POSTGRES

#define INTSTYLE_POSTGRES   0

Definition at line 17 of file dt.h.

◆ INTSTYLE_POSTGRES_VERBOSE

#define INTSTYLE_POSTGRES_VERBOSE   1

Definition at line 18 of file dt.h.

◆ INTSTYLE_SQL_STANDARD

#define INTSTYLE_SQL_STANDARD   2

Definition at line 19 of file dt.h.

◆ INVALID

#define INVALID   "invalid"

Definition at line 36 of file dt.h.

◆ IS_VALID_JULIAN

#define IS_VALID_JULIAN (   y,
  m,
 
)
Value:
(((y) > JULIAN_MINYEAR || \
((y) == JULIAN_MINYEAR && ((m) >= JULIAN_MINMONTH))) && \
((y) < JULIAN_MAXYEAR || \
((y) == JULIAN_MAXYEAR && ((m) < JULIAN_MAXMONTH))))
#define JULIAN_MINYEAR
Definition: dt.h:273
#define JULIAN_MAXMONTH
Definition: dt.h:277
#define JULIAN_MINMONTH
Definition: dt.h:274
#define JULIAN_MAXYEAR
Definition: dt.h:276

Definition at line 280 of file dt.h.

◆ IS_VALID_TIMESTAMP

#define IS_VALID_TIMESTAMP (   t)    (MIN_TIMESTAMP <= (t) && (t) < END_TIMESTAMP)

Definition at line 289 of file dt.h.

◆ IS_VALID_UTIME

#define IS_VALID_UTIME (   y,
  m,
 
)
Value:
((((y) > UTIME_MINYEAR) \
|| (((y) == UTIME_MINYEAR) && (((m) > UTIME_MINMONTH) \
|| (((m) == UTIME_MINMONTH) && ((d) >= UTIME_MINDAY))))) \
&& (((y) < UTIME_MAXYEAR) \
|| (((y) == UTIME_MAXYEAR) && (((m) < UTIME_MAXMONTH) \
|| (((m) == UTIME_MAXMONTH) && ((d) <= UTIME_MAXDAY))))))
#define UTIME_MAXMONTH
Definition: dt.h:295
#define UTIME_MINYEAR
Definition: dt.h:291
#define UTIME_MAXDAY
Definition: dt.h:296
#define UTIME_MAXYEAR
Definition: dt.h:294
#define UTIME_MINMONTH
Definition: dt.h:292
#define UTIME_MINDAY
Definition: dt.h:293

Definition at line 298 of file dt.h.

Referenced by timestamp2tm().

◆ isleap

#define isleap (   y)    (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))

Definition at line 267 of file dt.h.

◆ ISODATE

#define ISODATE   22

Definition at line 114 of file dt.h.

◆ ISOTIME

#define ISOTIME   23

Definition at line 115 of file dt.h.

◆ JULIAN

#define JULIAN   4

Definition at line 94 of file dt.h.

◆ JULIAN_MAXDAY

#define JULIAN_MAXDAY   (3)

Definition at line 278 of file dt.h.

◆ JULIAN_MAXMONTH

#define JULIAN_MAXMONTH   (6)

Definition at line 277 of file dt.h.

◆ JULIAN_MAXYEAR

#define JULIAN_MAXYEAR   (5874898)

Definition at line 276 of file dt.h.

◆ JULIAN_MINDAY

#define JULIAN_MINDAY   (24)

Definition at line 275 of file dt.h.

◆ JULIAN_MINMONTH

#define JULIAN_MINMONTH   (11)

Definition at line 274 of file dt.h.

◆ JULIAN_MINYEAR

#define JULIAN_MINYEAR   (-4713)

Definition at line 273 of file dt.h.

◆ LATE

#define LATE   "infinity"

Definition at line 38 of file dt.h.

◆ MAX_INTERVAL_PRECISION

#define MAX_INTERVAL_PRECISION   6

Definition at line 24 of file dt.h.

◆ MAXDATEFIELDS

#define MAXDATEFIELDS   25

Definition at line 198 of file dt.h.

◆ MAXDATELEN

#define MAXDATELEN   128

Definition at line 196 of file dt.h.

◆ MAXTZLEN

#define MAXTZLEN   10

Definition at line 8 of file dt.h.

◆ MICROSECOND

#define MICROSECOND   14

Definition at line 104 of file dt.h.

◆ MILLISECOND

#define MILLISECOND   13

Definition at line 103 of file dt.h.

◆ MIN_TIMESTAMP

#define MIN_TIMESTAMP   INT64CONST(-211813488000000000)

Definition at line 286 of file dt.h.

◆ MINS_PER_HOUR

#define MINS_PER_HOUR   60

Definition at line 256 of file dt.h.

◆ MINUTE

#define MINUTE   11

Definition at line 101 of file dt.h.

◆ MONTH

#define MONTH   1

Definition at line 91 of file dt.h.

◆ MONTHS_PER_YEAR

#define MONTHS_PER_YEAR   12

Definition at line 236 of file dt.h.

◆ NOW

#define NOW   "now"

Definition at line 39 of file dt.h.

◆ PM

#define PM   1

Definition at line 70 of file dt.h.

◆ RESERV

#define RESERV   0

Definition at line 90 of file dt.h.

◆ SECOND

#define SECOND   12

Definition at line 102 of file dt.h.

◆ SECS_PER_DAY

#define SECS_PER_DAY   86400

Definition at line 253 of file dt.h.

◆ SECS_PER_HOUR

#define SECS_PER_HOUR   3600

Definition at line 254 of file dt.h.

◆ SECS_PER_MINUTE

#define SECS_PER_MINUTE   60

Definition at line 255 of file dt.h.

◆ SECS_PER_YEAR

#define SECS_PER_YEAR   (36525 * 864) /* avoid floating-point computation */

Definition at line 252 of file dt.h.

◆ TIMESTAMP_IS_NOBEGIN

#define TIMESTAMP_IS_NOBEGIN (   j)    ((j) == DT_NOBEGIN)

Definition at line 310 of file dt.h.

◆ TIMESTAMP_IS_NOEND

#define TIMESTAMP_IS_NOEND (   j)    ((j) == DT_NOEND)

Definition at line 311 of file dt.h.

◆ TIMESTAMP_NOBEGIN

#define TIMESTAMP_NOBEGIN (   j)    do {(j) = DT_NOBEGIN;} while (0)

Definition at line 308 of file dt.h.

◆ TIMESTAMP_NOEND

#define TIMESTAMP_NOEND (   j)    do {(j) = DT_NOEND;} while (0)

Definition at line 309 of file dt.h.

◆ TIMESTAMP_NOT_FINITE

#define TIMESTAMP_NOT_FINITE (   j)    (TIMESTAMP_IS_NOBEGIN(j) || TIMESTAMP_IS_NOEND(j))

Definition at line 312 of file dt.h.

◆ TMODULO

#define TMODULO (   t,
  q,
 
)
Value:
do { \
(q) = ((t) / (u)); \
if ((q) != 0) (t) -= ((q) * (u)); \
} while(0)

Definition at line 228 of file dt.h.

◆ TODAY

#define TODAY   "today"

Definition at line 40 of file dt.h.

◆ TOKMAXLEN

#define TOKMAXLEN   10

Definition at line 200 of file dt.h.

◆ TOMORROW

#define TOMORROW   "tomorrow"

Definition at line 41 of file dt.h.

◆ TZ

#define TZ   5 /* fixed-offset timezone abbreviation */

Definition at line 95 of file dt.h.

◆ UNITS

#define UNITS   17

Definition at line 107 of file dt.h.

◆ UNKNOWN_FIELD

#define UNKNOWN_FIELD   31

Definition at line 119 of file dt.h.

◆ USE_GERMAN_DATES

#define USE_GERMAN_DATES   3

Definition at line 15 of file dt.h.

◆ USE_ISO_DATES

#define USE_ISO_DATES   1

Definition at line 13 of file dt.h.

◆ USE_POSTGRES_DATES

#define USE_POSTGRES_DATES   0

Definition at line 12 of file dt.h.

◆ USE_SQL_DATES

#define USE_SQL_DATES   2

Definition at line 14 of file dt.h.

◆ USECS_PER_DAY

#define USECS_PER_DAY   INT64CONST(86400000000)

Definition at line 258 of file dt.h.

◆ USECS_PER_HOUR

#define USECS_PER_HOUR   INT64CONST(3600000000)

Definition at line 259 of file dt.h.

◆ USECS_PER_MINUTE

#define USECS_PER_MINUTE   INT64CONST(60000000)

Definition at line 260 of file dt.h.

◆ USECS_PER_SEC

#define USECS_PER_SEC   INT64CONST(1000000)

Definition at line 261 of file dt.h.

◆ UTIME_MAXDAY

#define UTIME_MAXDAY   (18)

Definition at line 296 of file dt.h.

◆ UTIME_MAXMONTH

#define UTIME_MAXMONTH   (01)

Definition at line 295 of file dt.h.

◆ UTIME_MAXYEAR

#define UTIME_MAXYEAR   (2038)

Definition at line 294 of file dt.h.

◆ UTIME_MINDAY

#define UTIME_MINDAY   (14)

Definition at line 293 of file dt.h.

◆ UTIME_MINMONTH

#define UTIME_MINMONTH   (12)

Definition at line 292 of file dt.h.

◆ UTIME_MINYEAR

#define UTIME_MINYEAR   (1901)

Definition at line 291 of file dt.h.

◆ YEAR

#define YEAR   2

Definition at line 92 of file dt.h.

◆ YESTERDAY

#define YESTERDAY   "yesterday"

Definition at line 42 of file dt.h.

◆ ZULU

#define ZULU   "zulu"

Definition at line 43 of file dt.h.

Typedef Documentation

◆ fsec_t

Definition at line 10 of file dt.h.

Function Documentation

◆ CheckDateTokenTables()

bool CheckDateTokenTables ( void  )

Definition at line 4464 of file datetime.c.

References Assert, CheckDateTokenTable(), date2j(), POSTGRES_EPOCH_JDATE, szdatetktbl, szdeltatktbl, and UNIX_EPOCH_JDATE.

Referenced by PostmasterMain().

4465 {
4466  bool ok = true;
4467 
4468  Assert(UNIX_EPOCH_JDATE == date2j(1970, 1, 1));
4469  Assert(POSTGRES_EPOCH_JDATE == date2j(2000, 1, 1));
4470 
4471  ok &= CheckDateTokenTable("datetktbl", datetktbl, szdatetktbl);
4472  ok &= CheckDateTokenTable("deltatktbl", deltatktbl, szdeltatktbl);
4473  return ok;
4474 }
static const datetkn datetktbl[]
Definition: datetime.c:90
static int szdatetktbl
Definition: datetime.c:168
static bool CheckDateTokenTable(const char *tablename, const datetkn *base, int nel)
Definition: datetime.c:4432
static const datetkn deltatktbl[]
Definition: datetime.c:174
int date2j(int y, int m, int d)
Definition: datetime.c:292
static int szdeltatktbl
Definition: datetime.c:241
#define Assert(condition)
Definition: c.h:670
#define UNIX_EPOCH_JDATE
Definition: timestamp.h:162
#define POSTGRES_EPOCH_JDATE
Definition: timestamp.h:163

◆ date2j()

int date2j ( int  ,
int  ,
int   
)

Definition at line 292 of file datetime.c.

Referenced by abstime_date(), CheckDateTokenTables(), date2isoweek(), date2isoyear(), date2isoyearday(), date_in(), DCH_to_char(), DecodeDateTime(), DecodeNumber(), DetermineTimeZoneOffsetInternal(), EncodeDateTime(), GetSQLCurrentDate(), isoweek2j(), make_date(), make_timestamp_internal(), PGTYPESdate_dayofweek(), PGTYPESdate_defmt_asc(), PGTYPESdate_fmt_asc(), PGTYPESdate_from_asc(), PGTYPESdate_julmdy(), PGTYPESdate_mdyjul(), PGTYPESdate_to_asc(), PGTYPESdate_today(), timestamp2tm(), timestamp_date(), timestamp_part(), timestamp_pl_interval(), timestamp_to_char(), timestamptz_date(), timestamptz_part(), timestamptz_pl_interval(), timestamptz_to_char(), tm2abstime(), tm2timestamp(), to_date(), and ValidateDate().

293 {
294  int julian;
295  int century;
296 
297  if (m > 2)
298  {
299  m += 1;
300  y += 4800;
301  }
302  else
303  {
304  m += 13;
305  y += 4799;
306  }
307 
308  century = y / 100;
309  julian = y * 365 - 32167;
310  julian += y / 4 - century + century / 4;
311  julian += 7834 * m / 256 + d;
312 
313  return julian;
314 } /* date2j() */

◆ DecodeDateTime()

int DecodeDateTime ( char **  ,
int *  ,
int  ,
int *  ,
struct tm ,
fsec_t ,
bool   
)

Definition at line 1785 of file dt_common.c.

References ADBC, AM, AMPM, BC, date2j(), DAY, day_tab, DecodeDate(), DecodeNumber(), DecodeNumberField(), DecodePosixTimezone(), DecodeSpecial(), DecodeTime(), DecodeTimezone(), DOW, dt2time(), DTK_DATE, DTK_DATE_M, DTK_DAY, DTK_HOUR, DTK_JULIAN, DTK_M, DTK_MINUTE, DTK_MONTH, DTK_NOW, DTK_NUMBER, DTK_SECOND, DTK_SPECIAL, DTK_STRING, DTK_TIME, DTK_TIME_M, DTK_TODAY, DTK_TOMORROW, DTK_TZ, DTK_YEAR, DTK_YESTERDAY, DTK_ZULU, DTZ, DTZMOD, GetCurrentDateTime(), HOUR, HR24, i, IGNORE_DTF, isleap, ISOTIME, j2date(), MINUTE, MONTH, PM, RESERV, SECOND, generate_unaccent_rules::type, TZ, UNITS, USECS_PER_DAY, val, and YEAR.

1787 {
1788  int fmask = 0,
1789  tmask,
1790  type;
1791  int ptype = 0; /* "prefix type" for ISO y2001m02d04 format */
1792  int i;
1793  int val;
1794  int mer = HR24;
1795  bool haveTextMonth = false;
1796  bool is2digits = false;
1797  bool bc = false;
1798  int t = 0;
1799  int *tzp = &t;
1800 
1801  /***
1802  * We'll insist on at least all of the date fields, but initialize the
1803  * remaining fields in case they are not set later...
1804  ***/
1805  *dtype = DTK_DATE;
1806  tm->tm_hour = 0;
1807  tm->tm_min = 0;
1808  tm->tm_sec = 0;
1809  *fsec = 0;
1810  /* don't know daylight savings time status apriori */
1811  tm->tm_isdst = -1;
1812  if (tzp != NULL)
1813  *tzp = 0;
1814 
1815  for (i = 0; i < nf; i++)
1816  {
1817  switch (ftype[i])
1818  {
1819  case DTK_DATE:
1820  /***
1821  * Integral julian day with attached time zone?
1822  * All other forms with JD will be separated into
1823  * distinct fields, so we handle just this case here.
1824  ***/
1825  if (ptype == DTK_JULIAN)
1826  {
1827  char *cp;
1828  int val;
1829 
1830  if (tzp == NULL)
1831  return -1;
1832 
1833  val = strtol(field[i], &cp, 10);
1834  if (*cp != '-')
1835  return -1;
1836 
1837  j2date(val, &tm->tm_year, &tm->tm_mon, &tm->tm_mday);
1838  /* Get the time zone from the end of the string */
1839  if (DecodeTimezone(cp, tzp) != 0)
1840  return -1;
1841 
1842  tmask = DTK_DATE_M | DTK_TIME_M | DTK_M(TZ);
1843  ptype = 0;
1844  break;
1845  }
1846  /***
1847  * Already have a date? Then this might be a POSIX time
1848  * zone with an embedded dash (e.g. "PST-3" == "EST") or
1849  * a run-together time with trailing time zone (e.g. hhmmss-zz).
1850  * - thomas 2001-12-25
1851  ***/
1852  else if (((fmask & DTK_DATE_M) == DTK_DATE_M)
1853  || (ptype != 0))
1854  {
1855  /* No time zone accepted? Then quit... */
1856  if (tzp == NULL)
1857  return -1;
1858 
1859  if (isdigit((unsigned char) *field[i]) || ptype != 0)
1860  {
1861  char *cp;
1862 
1863  if (ptype != 0)
1864  {
1865  /* Sanity check; should not fail this test */
1866  if (ptype != DTK_TIME)
1867  return -1;
1868  ptype = 0;
1869  }
1870 
1871  /*
1872  * Starts with a digit but we already have a time
1873  * field? Then we are in trouble with a date and time
1874  * already...
1875  */
1876  if ((fmask & DTK_TIME_M) == DTK_TIME_M)
1877  return -1;
1878 
1879  if ((cp = strchr(field[i], '-')) == NULL)
1880  return -1;
1881 
1882  /* Get the time zone from the end of the string */
1883  if (DecodeTimezone(cp, tzp) != 0)
1884  return -1;
1885  *cp = '\0';
1886 
1887  /*
1888  * Then read the rest of the field as a concatenated
1889  * time
1890  */
1891  if ((ftype[i] = DecodeNumberField(strlen(field[i]), field[i], fmask,
1892  &tmask, tm, fsec, &is2digits)) < 0)
1893  return -1;
1894 
1895  /*
1896  * modify tmask after returning from
1897  * DecodeNumberField()
1898  */
1899  tmask |= DTK_M(TZ);
1900  }
1901  else
1902  {
1903  if (DecodePosixTimezone(field[i], tzp) != 0)
1904  return -1;
1905 
1906  ftype[i] = DTK_TZ;
1907  tmask = DTK_M(TZ);
1908  }
1909  }
1910  else if (DecodeDate(field[i], fmask, &tmask, tm, EuroDates) != 0)
1911  return -1;
1912  break;
1913 
1914  case DTK_TIME:
1915  if (DecodeTime(field[i], &tmask, tm, fsec) != 0)
1916  return -1;
1917 
1918  /*
1919  * Check upper limit on hours; other limits checked in
1920  * DecodeTime()
1921  */
1922  /* test for > 24:00:00 */
1923  if (tm->tm_hour > 24 ||
1924  (tm->tm_hour == 24 && (tm->tm_min > 0 || tm->tm_sec > 0)))
1925  return -1;
1926  break;
1927 
1928  case DTK_TZ:
1929  {
1930  int tz;
1931 
1932  if (tzp == NULL)
1933  return -1;
1934 
1935  if (DecodeTimezone(field[i], &tz) != 0)
1936  return -1;
1937 
1938  /*
1939  * Already have a time zone? Then maybe this is the second
1940  * field of a POSIX time: EST+3 (equivalent to PST)
1941  */
1942  if (i > 0 && (fmask & DTK_M(TZ)) != 0 &&
1943  ftype[i - 1] == DTK_TZ &&
1944  isalpha((unsigned char) *field[i - 1]))
1945  {
1946  *tzp -= tz;
1947  tmask = 0;
1948  }
1949  else
1950  {
1951  *tzp = tz;
1952  tmask = DTK_M(TZ);
1953  }
1954  }
1955  break;
1956 
1957  case DTK_NUMBER:
1958 
1959  /*
1960  * Was this an "ISO date" with embedded field labels? An
1961  * example is "y2001m02d04" - thomas 2001-02-04
1962  */
1963  if (ptype != 0)
1964  {
1965  char *cp;
1966  int val;
1967 
1968  val = strtol(field[i], &cp, 10);
1969 
1970  /*
1971  * only a few kinds are allowed to have an embedded
1972  * decimal
1973  */
1974  if (*cp == '.')
1975  switch (ptype)
1976  {
1977  case DTK_JULIAN:
1978  case DTK_TIME:
1979  case DTK_SECOND:
1980  break;
1981  default:
1982  return 1;
1983  break;
1984  }
1985  else if (*cp != '\0')
1986  return -1;
1987 
1988  switch (ptype)
1989  {
1990  case DTK_YEAR:
1991  tm->tm_year = val;
1992  tmask = DTK_M(YEAR);
1993  break;
1994 
1995  case DTK_MONTH:
1996 
1997  /*
1998  * already have a month and hour? then assume
1999  * minutes
2000  */
2001  if ((fmask & DTK_M(MONTH)) != 0 &&
2002  (fmask & DTK_M(HOUR)) != 0)
2003  {
2004  tm->tm_min = val;
2005  tmask = DTK_M(MINUTE);
2006  }
2007  else
2008  {
2009  tm->tm_mon = val;
2010  tmask = DTK_M(MONTH);
2011  }
2012  break;
2013 
2014  case DTK_DAY:
2015  tm->tm_mday = val;
2016  tmask = DTK_M(DAY);
2017  break;
2018 
2019  case DTK_HOUR:
2020  tm->tm_hour = val;
2021  tmask = DTK_M(HOUR);
2022  break;
2023 
2024  case DTK_MINUTE:
2025  tm->tm_min = val;
2026  tmask = DTK_M(MINUTE);
2027  break;
2028 
2029  case DTK_SECOND:
2030  tm->tm_sec = val;
2031  tmask = DTK_M(SECOND);
2032  if (*cp == '.')
2033  {
2034  double frac;
2035 
2036  frac = strtod(cp, &cp);
2037  if (*cp != '\0')
2038  return -1;
2039  *fsec = frac * 1000000;
2040  }
2041  break;
2042 
2043  case DTK_TZ:
2044  tmask = DTK_M(TZ);
2045  if (DecodeTimezone(field[i], tzp) != 0)
2046  return -1;
2047  break;
2048 
2049  case DTK_JULIAN:
2050  /***
2051  * previous field was a label for "julian date"?
2052  ***/
2053  tmask = DTK_DATE_M;
2054  j2date(val, &tm->tm_year, &tm->tm_mon, &tm->tm_mday);
2055  /* fractional Julian Day? */
2056  if (*cp == '.')
2057  {
2058  double time;
2059 
2060  time = strtod(cp, &cp);
2061  if (*cp != '\0')
2062  return -1;
2063 
2064  tmask |= DTK_TIME_M;
2065  dt2time((time * USECS_PER_DAY), &tm->tm_hour, &tm->tm_min, &tm->tm_sec, fsec);
2066  }
2067  break;
2068 
2069  case DTK_TIME:
2070  /* previous field was "t" for ISO time */
2071  if ((ftype[i] = DecodeNumberField(strlen(field[i]), field[i], (fmask | DTK_DATE_M),
2072  &tmask, tm, fsec, &is2digits)) < 0)
2073  return -1;
2074 
2075  if (tmask != DTK_TIME_M)
2076  return -1;
2077  break;
2078 
2079  default:
2080  return -1;
2081  break;
2082  }
2083 
2084  ptype = 0;
2085  *dtype = DTK_DATE;
2086  }
2087  else
2088  {
2089  char *cp;
2090  int flen;
2091 
2092  flen = strlen(field[i]);
2093  cp = strchr(field[i], '.');
2094 
2095  /* Embedded decimal and no date yet? */
2096  if (cp != NULL && !(fmask & DTK_DATE_M))
2097  {
2098  if (DecodeDate(field[i], fmask, &tmask, tm, EuroDates) != 0)
2099  return -1;
2100  }
2101  /* embedded decimal and several digits before? */
2102  else if (cp != NULL && flen - strlen(cp) > 2)
2103  {
2104  /*
2105  * Interpret as a concatenated date or time Set the
2106  * type field to allow decoding other fields later.
2107  * Example: 20011223 or 040506
2108  */
2109  if ((ftype[i] = DecodeNumberField(flen, field[i], fmask,
2110  &tmask, tm, fsec, &is2digits)) < 0)
2111  return -1;
2112  }
2113  else if (flen > 4)
2114  {
2115  if ((ftype[i] = DecodeNumberField(flen, field[i], fmask,
2116  &tmask, tm, fsec, &is2digits)) < 0)
2117  return -1;
2118  }
2119  /* otherwise it is a single date/time field... */
2120  else if (DecodeNumber(flen, field[i], fmask,
2121  &tmask, tm, fsec, &is2digits, EuroDates) != 0)
2122  return -1;
2123  }
2124  break;
2125 
2126  case DTK_STRING:
2127  case DTK_SPECIAL:
2128  type = DecodeSpecial(i, field[i], &val);
2129  if (type == IGNORE_DTF)
2130  continue;
2131 
2132  tmask = DTK_M(type);
2133  switch (type)
2134  {
2135  case RESERV:
2136  switch (val)
2137  {
2138  case DTK_NOW:
2139  tmask = (DTK_DATE_M | DTK_TIME_M | DTK_M(TZ));
2140  *dtype = DTK_DATE;
2142  break;
2143 
2144  case DTK_YESTERDAY:
2145  tmask = DTK_DATE_M;
2146  *dtype = DTK_DATE;
2148  j2date(date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - 1,
2149  &tm->tm_year, &tm->tm_mon, &tm->tm_mday);
2150  tm->tm_hour = 0;
2151  tm->tm_min = 0;
2152  tm->tm_sec = 0;
2153  break;
2154 
2155  case DTK_TODAY:
2156  tmask = DTK_DATE_M;
2157  *dtype = DTK_DATE;
2159  tm->tm_hour = 0;
2160  tm->tm_min = 0;
2161  tm->tm_sec = 0;
2162  break;
2163 
2164  case DTK_TOMORROW:
2165  tmask = DTK_DATE_M;
2166  *dtype = DTK_DATE;
2168  j2date(date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) + 1,
2169  &tm->tm_year, &tm->tm_mon, &tm->tm_mday);
2170  tm->tm_hour = 0;
2171  tm->tm_min = 0;
2172  tm->tm_sec = 0;
2173  break;
2174 
2175  case DTK_ZULU:
2176  tmask = (DTK_TIME_M | DTK_M(TZ));
2177  *dtype = DTK_DATE;
2178  tm->tm_hour = 0;
2179  tm->tm_min = 0;
2180  tm->tm_sec = 0;
2181  if (tzp != NULL)
2182  *tzp = 0;
2183  break;
2184 
2185  default:
2186  *dtype = val;
2187  }
2188 
2189  break;
2190 
2191  case MONTH:
2192 
2193  /*
2194  * already have a (numeric) month? then see if we can
2195  * substitute...
2196  */
2197  if ((fmask & DTK_M(MONTH)) && !haveTextMonth &&
2198  !(fmask & DTK_M(DAY)) && tm->tm_mon >= 1 && tm->tm_mon <= 31)
2199  {
2200  tm->tm_mday = tm->tm_mon;
2201  tmask = DTK_M(DAY);
2202  }
2203  haveTextMonth = true;
2204  tm->tm_mon = val;
2205  break;
2206 
2207  case DTZMOD:
2208 
2209  /*
2210  * daylight savings time modifier (solves "MET DST"
2211  * syntax)
2212  */
2213  tmask |= DTK_M(DTZ);
2214  tm->tm_isdst = 1;
2215  if (tzp == NULL)
2216  return -1;
2217  *tzp -= val;
2218  break;
2219 
2220  case DTZ:
2221 
2222  /*
2223  * set mask for TZ here _or_ check for DTZ later when
2224  * getting default timezone
2225  */
2226  tmask |= DTK_M(TZ);
2227  tm->tm_isdst = 1;
2228  if (tzp == NULL)
2229  return -1;
2230  *tzp = -val;
2231  ftype[i] = DTK_TZ;
2232  break;
2233 
2234  case TZ:
2235  tm->tm_isdst = 0;
2236  if (tzp == NULL)
2237  return -1;
2238  *tzp = -val;
2239  ftype[i] = DTK_TZ;
2240  break;
2241 
2242  case IGNORE_DTF:
2243  break;
2244 
2245  case AMPM:
2246  mer = val;
2247  break;
2248 
2249  case ADBC:
2250  bc = (val == BC);
2251  break;
2252 
2253  case DOW:
2254  tm->tm_wday = val;
2255  break;
2256 
2257  case UNITS:
2258  tmask = 0;
2259  ptype = val;
2260  break;
2261 
2262  case ISOTIME:
2263 
2264  /*
2265  * This is a filler field "t" indicating that the next
2266  * field is time. Try to verify that this is sensible.
2267  */
2268  tmask = 0;
2269 
2270  /* No preceding date? Then quit... */
2271  if ((fmask & DTK_DATE_M) != DTK_DATE_M)
2272  return -1;
2273 
2274  /***
2275  * We will need one of the following fields:
2276  * DTK_NUMBER should be hhmmss.fff
2277  * DTK_TIME should be hh:mm:ss.fff
2278  * DTK_DATE should be hhmmss-zz
2279  ***/
2280  if (i >= nf - 1 ||
2281  (ftype[i + 1] != DTK_NUMBER &&
2282  ftype[i + 1] != DTK_TIME &&
2283  ftype[i + 1] != DTK_DATE))
2284  return -1;
2285 
2286  ptype = val;
2287  break;
2288 
2289  default:
2290  return -1;
2291  }
2292  break;
2293 
2294  default:
2295  return -1;
2296  }
2297 
2298  if (tmask & fmask)
2299  return -1;
2300  fmask |= tmask;
2301  }
2302 
2303  /* there is no year zero in AD/BC notation; i.e. "1 BC" == year 0 */
2304  if (bc)
2305  {
2306  if (tm->tm_year > 0)
2307  tm->tm_year = -(tm->tm_year - 1);
2308  else
2309  return -1;
2310  }
2311  else if (is2digits)
2312  {
2313  if (tm->tm_year < 70)
2314  tm->tm_year += 2000;
2315  else if (tm->tm_year < 100)
2316  tm->tm_year += 1900;
2317  }
2318 
2319  if (mer != HR24 && tm->tm_hour > 12)
2320  return -1;
2321  if (mer == AM && tm->tm_hour == 12)
2322  tm->tm_hour = 0;
2323  else if (mer == PM && tm->tm_hour != 12)
2324  tm->tm_hour += 12;
2325 
2326  /* do additional checking for full date specs... */
2327  if (*dtype == DTK_DATE)
2328  {
2329  if ((fmask & DTK_DATE_M) != DTK_DATE_M)
2330  return ((fmask & DTK_TIME_M) == DTK_TIME_M) ? 1 : -1;
2331 
2332  /*
2333  * check for valid day of month, now that we know for sure the month
2334  * and year...
2335  */
2336  if (tm->tm_mday < 1 || tm->tm_mday > day_tab[isleap(tm->tm_year)][tm->tm_mon - 1])
2337  return -1;
2338 
2339  /*
2340  * backend tried to find local timezone here but we don't use the
2341  * result afterwards anyway so we only check for this error: daylight
2342  * savings time modifier but no standard timezone?
2343  */
2344  if ((fmask & DTK_DATE_M) == DTK_DATE_M && tzp != NULL && !(fmask & DTK_M(TZ)) && (fmask & DTK_M(DTZMOD)))
2345  return -1;
2346  }
2347 
2348  return 0;
2349 } /* DecodeDateTime() */
static int DecodeNumberField(int len, char *str, int fmask, int *tmask, struct tm *tm, fsec_t *fsec, bool *is2digits)
Definition: dt_common.c:1091
#define PM
Definition: datetime.h:73
#define DAY
Definition: datetime.h:94
#define UNITS
Definition: datetime.h:108
#define IGNORE_DTF
Definition: datetime.h:99
int tm_wday
Definition: pgtime.h:33
#define DTK_JULIAN
Definition: datetime.h:176
#define DTK_YEAR
Definition: datetime.h:170
int tm_isdst
Definition: pgtime.h:35
#define YEAR
Definition: datetime.h:93
int tm_hour
Definition: pgtime.h:29
#define isleap(y)
Definition: datetime.h:273
void GetCurrentDateTime(struct tm *tm)
Definition: dt_common.c:1062
#define DTK_TIME_M
Definition: datetime.h:195
#define TZ
Definition: datetime.h:96
#define SECOND
Definition: datetime.h:103
#define DTK_TODAY
Definition: datetime.h:158
#define DTK_TOMORROW
Definition: datetime.h:159
#define ADBC
Definition: datetime.h:109
static int DecodeTimezone(char *str, int *tzp)
Definition: dt_common.c:1504
int date2j(int y, int m, int d)
Definition: dt_common.c:585
#define DTK_DATE_M
Definition: datetime.h:194
static struct pg_tm tm
Definition: localtime.c:107
void j2date(int jd, int *year, int *month, int *day)
Definition: dt_common.c:610
#define DTK_MONTH
Definition: datetime.h:168
#define DTK_TZ
Definition: datetime.h:147
#define DTK_HOUR
Definition: datetime.h:165
#define DOW
Definition: datetime.h:107
#define AM
Definition: datetime.h:72
#define DTK_SECOND
Definition: datetime.h:163
int tm_mday
Definition: pgtime.h:30
int tm_mon
Definition: pgtime.h:31
int day_tab[2][13]
Definition: dt_common.c:13
#define DTK_YESTERDAY
Definition: datetime.h:157
#define DTK_NUMBER
Definition: datetime.h:142
#define MINUTE
Definition: datetime.h:102
#define USECS_PER_DAY
Definition: timestamp.h:91
#define MONTH
Definition: datetime.h:92
#define DTK_MINUTE
Definition: datetime.h:164
#define BC
Definition: datetime.h:77
#define ISOTIME
Definition: datetime.h:116
#define DTK_TIME
Definition: datetime.h:146
static int DecodeSpecial(int field, char *lowtoken, int *val)
Definition: dt_common.c:641
#define AMPM
Definition: datetime.h:100
#define DTK_STRING
Definition: datetime.h:143
#define DTK_DAY
Definition: datetime.h:166
int DecodeTime(char *str, int *tmask, struct tm *tm, fsec_t *fsec)
Definition: dt_common.c:1439
#define RESERV
Definition: datetime.h:91
#define DTZ
Definition: datetime.h:97
static int DecodeNumber(int flen, char *str, int fmask, int *tmask, struct tm *tm, fsec_t *fsec, bool *is2digits, bool EuroDates)
Definition: dt_common.c:1201
int tm_year
Definition: pgtime.h:32
#define DTK_NOW
Definition: datetime.h:156
static int DecodePosixTimezone(char *str, int *tzp)
Definition: dt_common.c:1549
int i
#define DTK_M(t)
Definition: datetime.h:190
#define HOUR
Definition: datetime.h:101
void dt2time(double jd, int *hour, int *min, int *sec, fsec_t *fsec)
Definition: dt_common.c:1070
#define DTK_ZULU
Definition: datetime.h:160
int tm_sec
Definition: pgtime.h:27
#define DTZMOD
Definition: datetime.h:123
static int DecodeDate(char *str, int fmask, int *tmask, struct tm *tm, bool EuroDates)
Definition: dt_common.c:1310
int tm_min
Definition: pgtime.h:28
long val
Definition: informix.c:689
#define DTK_DATE
Definition: datetime.h:145
#define HR24
Definition: datetime.h:74
#define DTK_SPECIAL
Definition: datetime.h:150

◆ DecodeInterval()

int DecodeInterval ( char **  ,
int *  ,
int  ,
int *  ,
struct tm ,
fsec_t  
)

Definition at line 336 of file interval.c.

References AdjustFractDays(), AdjustFractSeconds(), AGO, Assert, ClearPgTm(), DAY, DAYS_PER_MONTH, DecodeTime(), DecodeUnits(), DTERR_BAD_FORMAT, DTERR_FIELD_OVERFLOW, DTK_ALL_SECS_M, DTK_CENTURY, DTK_DATE, DTK_DATE_M, DTK_DAY, DTK_DECADE, DTK_DELTA, DTK_HOUR, DTK_M, DTK_MICROSEC, DTK_MILLENNIUM, DTK_MILLISEC, DTK_MINUTE, DTK_MONTH, DTK_NUMBER, DTK_SECOND, DTK_SPECIAL, DTK_STRING, DTK_TIME, DTK_TIME_M, DTK_TZ, DTK_WEEK, DTK_YEAR, HOUR, i, IGNORE_DTF, INTERVAL_FULL_RANGE, INTERVAL_MASK, IntervalStyle, INTSTYLE_POSTGRES_VERBOSE, INTSTYLE_SQL_STANDARD, MICROSECOND, MILLISECOND, MINUTE, MONTH, MONTHS_PER_YEAR, range(), RESERV, rint(), SECOND, SECS_PER_DAY, SECS_PER_HOUR, SECS_PER_MINUTE, strtoint(), generate_unaccent_rules::type, TZ, UNITS, USECS_PER_SEC, val, and YEAR.

Referenced by PGTYPESinterval_from_asc().

338 {
341  bool is_before = false;
342  char *cp;
343  int fmask = 0,
344  tmask,
345  type;
346  int i;
347  int dterr;
348  int val;
349  double fval;
350 
351  *dtype = DTK_DELTA;
352  type = IGNORE_DTF;
353  ClearPgTm(tm, fsec);
354 
355  /* read through list backwards to pick up units before values */
356  for (i = nf - 1; i >= 0; i--)
357  {
358  switch (ftype[i])
359  {
360  case DTK_TIME:
361  dterr = DecodeTime(field[i], /* range, */
362  &tmask, tm, fsec);
363  if (dterr)
364  return dterr;
365  type = DTK_DAY;
366  break;
367 
368  case DTK_TZ:
369 
370  /*
371  * Timezone is a token with a leading sign character and at
372  * least one digit; there could be ':', '.', '-' embedded in
373  * it as well.
374  */
375  Assert(*field[i] == '-' || *field[i] == '+');
376 
377  /*
378  * Try for hh:mm or hh:mm:ss. If not, fall through to
379  * DTK_NUMBER case, which can handle signed float numbers and
380  * signed year-month values.
381  */
382  if (strchr(field[i] + 1, ':') != NULL &&
383  DecodeTime(field[i] + 1, /* INTERVAL_FULL_RANGE, */
384  &tmask, tm, fsec) == 0)
385  {
386  if (*field[i] == '-')
387  {
388  /* flip the sign on all fields */
389  tm->tm_hour = -tm->tm_hour;
390  tm->tm_min = -tm->tm_min;
391  tm->tm_sec = -tm->tm_sec;
392  *fsec = -(*fsec);
393  }
394 
395  /*
396  * Set the next type to be a day, if units are not
397  * specified. This handles the case of '1 +02:03' since we
398  * are reading right to left.
399  */
400  type = DTK_DAY;
401  tmask = DTK_M(TZ);
402  break;
403  }
404  /* FALL THROUGH */
405 
406  case DTK_DATE:
407  case DTK_NUMBER:
408  if (type == IGNORE_DTF)
409  {
410  /* use typmod to decide what rightmost field is */
411  switch (range)
412  {
413  case INTERVAL_MASK(YEAR):
414  type = DTK_YEAR;
415  break;
416  case INTERVAL_MASK(MONTH):
418  type = DTK_MONTH;
419  break;
420  case INTERVAL_MASK(DAY):
421  type = DTK_DAY;
422  break;
423  case INTERVAL_MASK(HOUR):
427  type = DTK_HOUR;
428  break;
429  case INTERVAL_MASK(MINUTE):
431  type = DTK_MINUTE;
432  break;
433  case INTERVAL_MASK(SECOND):
436  type = DTK_SECOND;
437  break;
438  default:
439  type = DTK_SECOND;
440  break;
441  }
442  }
443 
444  errno = 0;
445  val = strtoint(field[i], &cp, 10);
446  if (errno == ERANGE)
447  return DTERR_FIELD_OVERFLOW;
448 
449  if (*cp == '-')
450  {
451  /* SQL "years-months" syntax */
452  int val2;
453 
454  val2 = strtoint(cp + 1, &cp, 10);
455  if (errno == ERANGE || val2 < 0 || val2 >= MONTHS_PER_YEAR)
456  return DTERR_FIELD_OVERFLOW;
457  if (*cp != '\0')
458  return DTERR_BAD_FORMAT;
459  type = DTK_MONTH;
460  if (*field[i] == '-')
461  val2 = -val2;
462  val = val * MONTHS_PER_YEAR + val2;
463  fval = 0;
464  }
465  else if (*cp == '.')
466  {
467  errno = 0;
468  fval = strtod(cp, &cp);
469  if (*cp != '\0' || errno != 0)
470  return DTERR_BAD_FORMAT;
471 
472  if (*field[i] == '-')
473  fval = -fval;
474  }
475  else if (*cp == '\0')
476  fval = 0;
477  else
478  return DTERR_BAD_FORMAT;
479 
480  tmask = 0; /* DTK_M(type); */
481 
482  switch (type)
483  {
484  case DTK_MICROSEC:
485  *fsec += rint(val + fval);
486  tmask = DTK_M(MICROSECOND);
487  break;
488 
489  case DTK_MILLISEC:
490  *fsec += rint((val + fval) * 1000);
491  tmask = DTK_M(MILLISECOND);
492  break;
493 
494  case DTK_SECOND:
495  tm->tm_sec += val;
496  *fsec += rint(fval * 1000000);
497 
498  /*
499  * If any subseconds were specified, consider this
500  * microsecond and millisecond input as well.
501  */
502  if (fval == 0)
503  tmask = DTK_M(SECOND);
504  else
505  tmask = DTK_ALL_SECS_M;
506  break;
507 
508  case DTK_MINUTE:
509  tm->tm_min += val;
510  AdjustFractSeconds(fval, tm, fsec, SECS_PER_MINUTE);
511  tmask = DTK_M(MINUTE);
512  break;
513 
514  case DTK_HOUR:
515  tm->tm_hour += val;
516  AdjustFractSeconds(fval, tm, fsec, SECS_PER_HOUR);
517  tmask = DTK_M(HOUR);
518  type = DTK_DAY;
519  break;
520 
521  case DTK_DAY:
522  tm->tm_mday += val;
523  AdjustFractSeconds(fval, tm, fsec, SECS_PER_DAY);
524  tmask = (fmask & DTK_M(DAY)) ? 0 : DTK_M(DAY);
525  break;
526 
527  case DTK_WEEK:
528  tm->tm_mday += val * 7;
529  AdjustFractDays(fval, tm, fsec, 7);
530  tmask = (fmask & DTK_M(DAY)) ? 0 : DTK_M(DAY);
531  break;
532 
533  case DTK_MONTH:
534  tm->tm_mon += val;
535  AdjustFractDays(fval, tm, fsec, DAYS_PER_MONTH);
536  tmask = DTK_M(MONTH);
537  break;
538 
539  case DTK_YEAR:
540  tm->tm_year += val;
541  if (fval != 0)
542  tm->tm_mon += fval * MONTHS_PER_YEAR;
543  tmask = (fmask & DTK_M(YEAR)) ? 0 : DTK_M(YEAR);
544  break;
545 
546  case DTK_DECADE:
547  tm->tm_year += val * 10;
548  if (fval != 0)
549  tm->tm_mon += fval * MONTHS_PER_YEAR * 10;
550  tmask = (fmask & DTK_M(YEAR)) ? 0 : DTK_M(YEAR);
551  break;
552 
553  case DTK_CENTURY:
554  tm->tm_year += val * 100;
555  if (fval != 0)
556  tm->tm_mon += fval * MONTHS_PER_YEAR * 100;
557  tmask = (fmask & DTK_M(YEAR)) ? 0 : DTK_M(YEAR);
558  break;
559 
560  case DTK_MILLENNIUM:
561  tm->tm_year += val * 1000;
562  if (fval != 0)
563  tm->tm_mon += fval * MONTHS_PER_YEAR * 1000;
564  tmask = (fmask & DTK_M(YEAR)) ? 0 : DTK_M(YEAR);
565  break;
566 
567  default:
568  return DTERR_BAD_FORMAT;
569  }
570  break;
571 
572  case DTK_STRING:
573  case DTK_SPECIAL:
574  type = DecodeUnits(i, field[i], &val);
575  if (type == IGNORE_DTF)
576  continue;
577 
578  tmask = 0; /* DTK_M(type); */
579  switch (type)
580  {
581  case UNITS:
582  type = val;
583  break;
584 
585  case AGO:
586  is_before = true;
587  type = val;
588  break;
589 
590  case RESERV:
591  tmask = (DTK_DATE_M | DTK_TIME_M);
592  *dtype = val;
593  break;
594 
595  default:
596  return DTERR_BAD_FORMAT;
597  }
598  break;
599 
600  default:
601  return DTERR_BAD_FORMAT;
602  }
603 
604  if (tmask & fmask)
605  return DTERR_BAD_FORMAT;
606  fmask |= tmask;
607  }
608 
609  /* ensure that at least one time field has been found */
610  if (fmask == 0)
611  return DTERR_BAD_FORMAT;
612 
613  /* ensure fractional seconds are fractional */
614  if (*fsec != 0)
615  {
616  int sec;
617 
618  sec = *fsec / USECS_PER_SEC;
619  *fsec -= sec * USECS_PER_SEC;
620  tm->tm_sec += sec;
621  }
622 
623  /*----------
624  * The SQL standard defines the interval literal
625  * '-1 1:00:00'
626  * to mean "negative 1 days and negative 1 hours", while Postgres
627  * traditionally treats this as meaning "negative 1 days and positive
628  * 1 hours". In SQL_STANDARD intervalstyle, we apply the leading sign
629  * to all fields if there are no other explicit signs.
630  *
631  * We leave the signs alone if there are additional explicit signs.
632  * This protects us against misinterpreting postgres-style dump output,
633  * since the postgres-style output code has always put an explicit sign on
634  * all fields following a negative field. But note that SQL-spec output
635  * is ambiguous and can be misinterpreted on load! (So it's best practice
636  * to dump in postgres style, not SQL style.)
637  *----------
638  */
639  if (IntervalStyle == INTSTYLE_SQL_STANDARD && *field[0] == '-')
640  {
641  /* Check for additional explicit signs */
642  bool more_signs = false;
643 
644  for (i = 1; i < nf; i++)
645  {
646  if (*field[i] == '-' || *field[i] == '+')
647  {
648  more_signs = true;
649  break;
650  }
651  }
652 
653  if (!more_signs)
654  {
655  /*
656  * Rather than re-determining which field was field[0], just force
657  * 'em all negative.
658  */
659  if (*fsec > 0)
660  *fsec = -(*fsec);
661  if (tm->tm_sec > 0)
662  tm->tm_sec = -tm->tm_sec;
663  if (tm->tm_min > 0)
664  tm->tm_min = -tm->tm_min;
665  if (tm->tm_hour > 0)
666  tm->tm_hour = -tm->tm_hour;
667  if (tm->tm_mday > 0)
668  tm->tm_mday = -tm->tm_mday;
669  if (tm->tm_mon > 0)
670  tm->tm_mon = -tm->tm_mon;
671  if (tm->tm_year > 0)
672  tm->tm_year = -tm->tm_year;
673  }
674  }
675 
676  /* finally, AGO negates everything */
677  if (is_before)
678  {
679  *fsec = -(*fsec);
680  tm->tm_sec = -tm->tm_sec;
681  tm->tm_min = -tm->tm_min;
682  tm->tm_hour = -tm->tm_hour;
683  tm->tm_mday = -tm->tm_mday;
684  tm->tm_mon = -tm->tm_mon;
685  tm->tm_year = -tm->tm_year;
686  }
687 
688  return 0;
689 }
#define INTSTYLE_POSTGRES_VERBOSE
Definition: miscadmin.h:232
static void AdjustFractDays(double frac, struct tm *tm, fsec_t *fsec, int scale)
Definition: interval.c:53
#define DTERR_BAD_FORMAT
Definition: datetime.h:282
#define DTK_CENTURY
Definition: datetime.h:172
#define DAY
Definition: datetime.h:94
#define UNITS
Definition: datetime.h:108
#define IGNORE_DTF
Definition: datetime.h:99
#define DTK_WEEK
Definition: datetime.h:167
#define DTK_YEAR
Definition: datetime.h:170
#define USECS_PER_SEC
Definition: timestamp.h:94
#define YEAR
Definition: datetime.h:93
#define DTK_DELTA
Definition: datetime.h:162
int tm_hour
Definition: pgtime.h:29
#define AGO
Definition: datetime.h:111
#define DTK_TIME_M
Definition: datetime.h:195
#define DTK_MILLENNIUM
Definition: datetime.h:173
int IntervalStyle
Definition: globals.c:109
#define TZ
Definition: datetime.h:96
#define SECOND
Definition: datetime.h:103
int DecodeUnits(int field, char *lowtoken, int *val)
Definition: datetime.c:3728
#define INTERVAL_FULL_RANGE
Definition: timestamp.h:48
#define DTK_DATE_M
Definition: datetime.h:194
static struct pg_tm tm
Definition: localtime.c:107
static void ClearPgTm(struct tm *tm, fsec_t *fsec)
Definition: interval.c:106
#define DTK_MONTH
Definition: datetime.h:168
#define DTK_MILLISEC
Definition: datetime.h:174
#define MONTHS_PER_YEAR
Definition: timestamp.h:69
static int strtoint(const char *nptr, char **endptr, int base)
Definition: interval.c:19
#define DTK_DECADE
Definition: datetime.h:171
#define DTK_TZ
Definition: datetime.h:147
#define DTK_HOUR
Definition: datetime.h:165
#define DTERR_FIELD_OVERFLOW
Definition: datetime.h:283
#define MILLISECOND
Definition: datetime.h:104
#define SECS_PER_DAY
Definition: timestamp.h:86
#define DTK_SECOND
Definition: datetime.h:163
int tm_mday
Definition: pgtime.h:30
int tm_mon
Definition: pgtime.h:31
#define SECS_PER_MINUTE
Definition: timestamp.h:88
#define DTK_NUMBER
Definition: datetime.h:142
#define MINUTE
Definition: datetime.h:102
static struct cvec * range(struct vars *v, chr a, chr b, int cases)
Definition: regc_locale.c:416
double rint(double x)
Definition: rint.c:22
#define SECS_PER_HOUR
Definition: timestamp.h:87
#define MONTH
Definition: datetime.h:92
#define DTK_MINUTE
Definition: datetime.h:164
#define DTK_MICROSEC
Definition: datetime.h:175
#define DAYS_PER_MONTH
Definition: timestamp.h:77
#define DTK_TIME
Definition: datetime.h:146
static int DecodeTime(char *str, int fmask, int range, int *tmask, struct pg_tm *tm, fsec_t *fsec)
Definition: datetime.c:2558
static void AdjustFractSeconds(double frac, struct tm *tm, fsec_t *fsec, int scale)
Definition: interval.c:35
#define Assert(condition)
Definition: c.h:670
#define DTK_STRING
Definition: datetime.h:143
#define DTK_DAY
Definition: datetime.h:166
#define RESERV
Definition: datetime.h:91
#define DTK_ALL_SECS_M
Definition: datetime.h:193
#define INTERVAL_MASK(b)
Definition: timestamp.h:45
#define INTSTYLE_SQL_STANDARD
Definition: miscadmin.h:233
int tm_year
Definition: pgtime.h:32
int i
#define DTK_M(t)
Definition: datetime.h:190
#define HOUR
Definition: datetime.h:101
int tm_sec
Definition: pgtime.h:27
int tm_min
Definition: pgtime.h:28
long val
Definition: informix.c:689
#define DTK_DATE
Definition: datetime.h:145
#define DTK_SPECIAL
Definition: datetime.h:150
#define MICROSECOND
Definition: datetime.h:105

◆ DecodeTime()

int DecodeTime ( char *  ,
int *  ,
struct tm ,
fsec_t  
)

Definition at line 1439 of file dt_common.c.

References DTK_TIME_M, i, and USECS_PER_SEC.

Referenced by DecodeDateTime().

1440 {
1441  char *cp;
1442 
1443  *tmask = DTK_TIME_M;
1444 
1445  tm->tm_hour = strtol(str, &cp, 10);
1446  if (*cp != ':')
1447  return -1;
1448  str = cp + 1;
1449  tm->tm_min = strtol(str, &cp, 10);
1450  if (*cp == '\0')
1451  {
1452  tm->tm_sec = 0;
1453  *fsec = 0;
1454  }
1455  else if (*cp != ':')
1456  return -1;
1457  else
1458  {
1459  str = cp + 1;
1460  tm->tm_sec = strtol(str, &cp, 10);
1461  if (*cp == '\0')
1462  *fsec = 0;
1463  else if (*cp == '.')
1464  {
1465  char fstr[7];
1466  int i;
1467 
1468  cp++;
1469 
1470  /*
1471  * OK, we have at most six digits to care about. Let's construct a
1472  * string with those digits, zero-padded on the right, and then do
1473  * the conversion to an integer.
1474  *
1475  * XXX This truncates the seventh digit, unlike rounding it as the
1476  * backend does.
1477  */
1478  for (i = 0; i < 6; i++)
1479  fstr[i] = *cp != '\0' ? *cp++ : '0';
1480  fstr[i] = '\0';
1481  *fsec = strtol(fstr, &cp, 10);
1482  if (*cp != '\0')
1483  return -1;
1484  }
1485  else
1486  return -1;
1487  }
1488 
1489  /* do a sanity check */
1490  if (tm->tm_hour < 0 || tm->tm_min < 0 || tm->tm_min > 59 ||
1491  tm->tm_sec < 0 || tm->tm_sec > 59 || *fsec >= USECS_PER_SEC)
1492  return -1;
1493 
1494  return 0;
1495 } /* DecodeTime() */
#define USECS_PER_SEC
Definition: timestamp.h:94
int tm_hour
Definition: pgtime.h:29
#define DTK_TIME_M
Definition: datetime.h:195
static struct pg_tm tm
Definition: localtime.c:107
int i
int tm_sec
Definition: pgtime.h:27
int tm_min
Definition: pgtime.h:28

◆ DecodeUnits()

int DecodeUnits ( int  field,
char *  lowtoken,
int *  val 
)

Definition at line 3728 of file datetime.c.

References datebsearch(), szdeltatktbl, datetkn::token, TOKMAXLEN, generate_unaccent_rules::type, datetkn::type, UNKNOWN_FIELD, and datetkn::value.

Referenced by DecodeInterval(), interval_part(), interval_trunc(), time_part(), timestamp_part(), timestamp_trunc(), timestamptz_part(), timestamptz_trunc(), and timetz_part().

3729 {
3730  int type;
3731  const datetkn *tp;
3732 
3733  tp = deltacache[field];
3734  /* use strncmp so that we match truncated tokens */
3735  if (tp == NULL || strncmp(lowtoken, tp->token, TOKMAXLEN) != 0)
3736  {
3737  tp = datebsearch(lowtoken, deltatktbl, szdeltatktbl);
3738  }
3739  if (tp == NULL)
3740  {
3741  type = UNKNOWN_FIELD;
3742  *val = 0;
3743  }
3744  else
3745  {
3746  deltacache[field] = tp;
3747  type = tp->type;
3748  *val = tp->value;
3749  }
3750 
3751  return type;
3752 } /* DecodeUnits() */
static const datetkn * deltacache[MAXDATEFIELDS]
Definition: datetime.c:249
#define UNKNOWN_FIELD
Definition: datetime.h:125
int32 value
Definition: datetime.h:214
char token[TOKMAXLEN+1]
Definition: datetime.h:212
static const datetkn * datebsearch(const char *key, const datetkn *base, int nel)
Definition: datetime.c:3810
static const datetkn deltatktbl[]
Definition: datetime.c:174
static int szdeltatktbl
Definition: datetime.c:241
char type
Definition: datetime.h:213
#define TOKMAXLEN
Definition: datetime.h:207
long val
Definition: informix.c:689

◆ dt2time()

void dt2time ( double  ,
int *  ,
int *  ,
int *  ,
fsec_t  
)

Definition at line 1070 of file dt_common.c.

References USECS_PER_HOUR, USECS_PER_MINUTE, and USECS_PER_SEC.

Referenced by DecodeDateTime().

1071 {
1072  int64 time;
1073 
1074  time = jd;
1075  *hour = time / USECS_PER_HOUR;
1076  time -= (*hour) * USECS_PER_HOUR;
1077  *min = time / USECS_PER_MINUTE;
1078  time -= (*min) * USECS_PER_MINUTE;
1079  *sec = time / USECS_PER_SEC;
1080  *fsec = time - (*sec * USECS_PER_SEC);
1081 } /* dt2time() */
#define USECS_PER_SEC
Definition: timestamp.h:94
#define USECS_PER_MINUTE
Definition: timestamp.h:93
#define USECS_PER_HOUR
Definition: timestamp.h:92

◆ EncodeDateOnly()

void EncodeDateOnly ( struct tm tm,
int  style,
char *  str,
bool  EuroDates 
)

Definition at line 675 of file dt_common.c.

References Assert, MONTHS_PER_YEAR, USE_GERMAN_DATES, USE_ISO_DATES, USE_POSTGRES_DATES, and USE_SQL_DATES.

676 {
677  Assert(tm->tm_mon >= 1 && tm->tm_mon <= MONTHS_PER_YEAR);
678 
679  switch (style)
680  {
681  case USE_ISO_DATES:
682  /* compatible with ISO date formats */
683  if (tm->tm_year > 0)
684  sprintf(str, "%04d-%02d-%02d",
685  tm->tm_year, tm->tm_mon, tm->tm_mday);
686  else
687  sprintf(str, "%04d-%02d-%02d %s",
688  -(tm->tm_year - 1), tm->tm_mon, tm->tm_mday, "BC");
689  break;
690 
691  case USE_SQL_DATES:
692  /* compatible with Oracle/Ingres date formats */
693  if (EuroDates)
694  sprintf(str, "%02d/%02d", tm->tm_mday, tm->tm_mon);
695  else
696  sprintf(str, "%02d/%02d", tm->tm_mon, tm->tm_mday);
697  if (tm->tm_year > 0)
698  sprintf(str + 5, "/%04d", tm->tm_year);
699  else
700  sprintf(str + 5, "/%04d %s", -(tm->tm_year - 1), "BC");
701  break;
702 
703  case USE_GERMAN_DATES:
704  /* German-style date format */
705  sprintf(str, "%02d.%02d", tm->tm_mday, tm->tm_mon);
706  if (tm->tm_year > 0)
707  sprintf(str + 5, ".%04d", tm->tm_year);
708  else
709  sprintf(str + 5, ".%04d %s", -(tm->tm_year - 1), "BC");
710  break;
711 
712  case USE_POSTGRES_DATES:
713  default:
714  /* traditional date-only style for Postgres */
715  if (EuroDates)
716  sprintf(str, "%02d-%02d", tm->tm_mday, tm->tm_mon);
717  else
718  sprintf(str, "%02d-%02d", tm->tm_mon, tm->tm_mday);
719  if (tm->tm_year > 0)
720  sprintf(str + 5, "-%04d", tm->tm_year);
721  else
722  sprintf(str + 5, "-%04d %s", -(tm->tm_year - 1), "BC");
723  break;
724  }
725 }
#define USE_SQL_DATES
Definition: miscadmin.h:212
#define USE_ISO_DATES
Definition: miscadmin.h:211
static struct pg_tm tm
Definition: localtime.c:107
#define MONTHS_PER_YEAR
Definition: timestamp.h:69
int tm_mday
Definition: pgtime.h:30
int tm_mon
Definition: pgtime.h:31
#define USE_POSTGRES_DATES
Definition: miscadmin.h:210
#define Assert(condition)
Definition: c.h:670
int tm_year
Definition: pgtime.h:32
#define USE_GERMAN_DATES
Definition: miscadmin.h:213

◆ EncodeDateTime()

void EncodeDateTime ( struct tm tm,
fsec_t  fsec,
bool  print_tz,
int  tz,
const char *  tzn,
int  style,
char *  str,
bool  EuroDates 
)

Definition at line 759 of file dt_common.c.

References date2j(), days, MAXTZLEN, MINS_PER_HOUR, months, SECS_PER_HOUR, TrimTrailingZeros(), USE_GERMAN_DATES, USE_ISO_DATES, USE_POSTGRES_DATES, and USE_SQL_DATES.

760 {
761  int day,
762  hour,
763  min;
764 
765  /*
766  * Negative tm_isdst means we have no valid time zone translation.
767  */
768  if (tm->tm_isdst < 0)
769  print_tz = false;
770 
771  switch (style)
772  {
773  case USE_ISO_DATES:
774  /* Compatible with ISO-8601 date formats */
775 
776  sprintf(str, "%04d-%02d-%02d %02d:%02d",
777  (tm->tm_year > 0) ? tm->tm_year : -(tm->tm_year - 1),
778  tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min);
779 
780  /*
781  * Print fractional seconds if any. The field widths here should
782  * be at least equal to MAX_TIMESTAMP_PRECISION.
783  */
784  if (fsec != 0)
785  {
786  sprintf(str + strlen(str), ":%02d.%06d", tm->tm_sec, fsec);
788  }
789  else
790  sprintf(str + strlen(str), ":%02d", tm->tm_sec);
791 
792  if (tm->tm_year <= 0)
793  sprintf(str + strlen(str), " BC");
794 
795  if (print_tz)
796  {
797  hour = -(tz / SECS_PER_HOUR);
798  min = (abs(tz) / MINS_PER_HOUR) % MINS_PER_HOUR;
799  if (min != 0)
800  sprintf(str + strlen(str), "%+03d:%02d", hour, min);
801  else
802  sprintf(str + strlen(str), "%+03d", hour);
803  }
804  break;
805 
806  case USE_SQL_DATES:
807  /* Compatible with Oracle/Ingres date formats */
808 
809  if (EuroDates)
810  sprintf(str, "%02d/%02d", tm->tm_mday, tm->tm_mon);
811  else
812  sprintf(str, "%02d/%02d", tm->tm_mon, tm->tm_mday);
813 
814  sprintf(str + 5, "/%04d %02d:%02d",
815  (tm->tm_year > 0) ? tm->tm_year : -(tm->tm_year - 1),
816  tm->tm_hour, tm->tm_min);
817 
818  /*
819  * Print fractional seconds if any. The field widths here should
820  * be at least equal to MAX_TIMESTAMP_PRECISION.
821  */
822  if (fsec != 0)
823  {
824  sprintf(str + strlen(str), ":%02d.%06d", tm->tm_sec, fsec);
826  }
827  else
828  sprintf(str + strlen(str), ":%02d", tm->tm_sec);
829 
830  if (tm->tm_year <= 0)
831  sprintf(str + strlen(str), " BC");
832 
833  /*
834  * Note: the uses of %.*s in this function would be risky if the
835  * timezone names ever contain non-ASCII characters. However, all
836  * TZ abbreviations in the Olson database are plain ASCII.
837  */
838 
839  if (print_tz)
840  {
841  if (tzn)
842  sprintf(str + strlen(str), " %.*s", MAXTZLEN, tzn);
843  else
844  {
845  hour = -(tz / SECS_PER_HOUR);
846  min = (abs(tz) / MINS_PER_HOUR) % MINS_PER_HOUR;
847  if (min != 0)
848  sprintf(str + strlen(str), "%+03d:%02d", hour, min);
849  else
850  sprintf(str + strlen(str), "%+03d", hour);
851  }
852  }
853  break;
854 
855  case USE_GERMAN_DATES:
856  /* German variant on European style */
857 
858  sprintf(str, "%02d.%02d", tm->tm_mday, tm->tm_mon);
859 
860  sprintf(str + 5, ".%04d %02d:%02d",
861  (tm->tm_year > 0) ? tm->tm_year : -(tm->tm_year - 1),
862  tm->tm_hour, tm->tm_min);
863 
864  /*
865  * Print fractional seconds if any. The field widths here should
866  * be at least equal to MAX_TIMESTAMP_PRECISION.
867  */
868  if (fsec != 0)
869  {
870  sprintf(str + strlen(str), ":%02d.%06d", tm->tm_sec, fsec);
872  }
873  else
874  sprintf(str + strlen(str), ":%02d", tm->tm_sec);
875 
876  if (tm->tm_year <= 0)
877  sprintf(str + strlen(str), " BC");
878 
879  if (print_tz)
880  {
881  if (tzn)
882  sprintf(str + strlen(str), " %.*s", MAXTZLEN, tzn);
883  else
884  {
885  hour = -(tz / SECS_PER_HOUR);
886  min = (abs(tz) / MINS_PER_HOUR) % MINS_PER_HOUR;
887  if (min != 0)
888  sprintf(str + strlen(str), "%+03d:%02d", hour, min);
889  else
890  sprintf(str + strlen(str), "%+03d", hour);
891  }
892  }
893  break;
894 
895  case USE_POSTGRES_DATES:
896  default:
897  /* Backward-compatible with traditional Postgres abstime dates */
898 
899  day = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday);
900  tm->tm_wday = (int) ((day + date2j(2000, 1, 1) + 1) % 7);
901 
902  memcpy(str, days[tm->tm_wday], 3);
903  strcpy(str + 3, " ");
904 
905  if (EuroDates)
906  sprintf(str + 4, "%02d %3s", tm->tm_mday, months[tm->tm_mon - 1]);
907  else
908  sprintf(str + 4, "%3s %02d", months[tm->tm_mon - 1], tm->tm_mday);
909 
910  sprintf(str + 10, " %02d:%02d", tm->tm_hour, tm->tm_min);
911 
912  /*
913  * Print fractional seconds if any. The field widths here should
914  * be at least equal to MAX_TIMESTAMP_PRECISION.
915  */
916  if (fsec != 0)
917  {
918  sprintf(str + strlen(str), ":%02d.%06d", tm->tm_sec, fsec);
920  }
921  else
922  sprintf(str + strlen(str), ":%02d", tm->tm_sec);
923 
924  sprintf(str + strlen(str), " %04d",
925  (tm->tm_year > 0) ? tm->tm_year : -(tm->tm_year - 1));
926  if (tm->tm_year <= 0)
927  sprintf(str + strlen(str), " BC");
928 
929  if (print_tz)
930  {
931  if (tzn)
932  sprintf(str + strlen(str), " %.*s", MAXTZLEN, tzn);
933  else
934  {
935  /*
936  * We have a time zone, but no string version. Use the
937  * numeric form, but be sure to include a leading space to
938  * avoid formatting something which would be rejected by
939  * the date/time parser later. - thomas 2001-10-19
940  */
941  hour = -(tz / SECS_PER_HOUR);
942  min = (abs(tz) / MINS_PER_HOUR) % MINS_PER_HOUR;
943  if (min != 0)
944  sprintf(str + strlen(str), " %+03d:%02d", hour, min);
945  else
946  sprintf(str + strlen(str), " %+03d", hour);
947  }
948  }
949  break;
950  }
951 }
char * days[]
Definition: dt_common.c:499
int tm_wday
Definition: pgtime.h:33
int tm_isdst
Definition: pgtime.h:35
int tm_hour
Definition: pgtime.h:29
#define USE_SQL_DATES
Definition: miscadmin.h:212
#define MAXTZLEN
Definition: miscadmin.h:238
int date2j(int y, int m, int d)
Definition: dt_common.c:585
#define MINS_PER_HOUR
Definition: timestamp.h:89
#define USE_ISO_DATES
Definition: miscadmin.h:211
static struct pg_tm tm
Definition: localtime.c:107
char * months[]
Definition: dt_common.c:497
int tm_mday
Definition: pgtime.h:30
int tm_mon
Definition: pgtime.h:31
#define USE_POSTGRES_DATES
Definition: miscadmin.h:210
#define SECS_PER_HOUR
Definition: timestamp.h:87
int tm_year
Definition: pgtime.h:32
#define USE_GERMAN_DATES
Definition: miscadmin.h:213
int tm_sec
Definition: pgtime.h:27
void TrimTrailingZeros(char *str)
Definition: dt_common.c:728
int tm_min
Definition: pgtime.h:28

◆ EncodeInterval()

void EncodeInterval ( struct tm tm,
fsec_t  fsec,
int  style,
char *  str 
)

Definition at line 773 of file interval.c.

References AddISO8601IntPart(), AddPostgresIntPart(), AddVerboseIntPart(), AppendSeconds(), INTSTYLE_ISO_8601, INTSTYLE_POSTGRES, INTSTYLE_POSTGRES_VERBOSE, INTSTYLE_SQL_STANDARD, MAX_INTERVAL_PRECISION, and generate_unaccent_rules::str.

Referenced by PGTYPESinterval_to_asc().

774 {
775  char *cp = str;
776  int year = tm->tm_year;
777  int mon = tm->tm_mon;
778  int mday = tm->tm_mday;
779  int hour = tm->tm_hour;
780  int min = tm->tm_min;
781  int sec = tm->tm_sec;
782  bool is_before = false;
783  bool is_zero = true;
784 
785  /*
786  * The sign of year and month are guaranteed to match, since they are
787  * stored internally as "month". But we'll need to check for is_before and
788  * is_zero when determining the signs of day and hour/minute/seconds
789  * fields.
790  */
791  switch (style)
792  {
793  /* SQL Standard interval format */
795  {
796  bool has_negative = year < 0 || mon < 0 ||
797  mday < 0 || hour < 0 ||
798  min < 0 || sec < 0 || fsec < 0;
799  bool has_positive = year > 0 || mon > 0 ||
800  mday > 0 || hour > 0 ||
801  min > 0 || sec > 0 || fsec > 0;
802  bool has_year_month = year != 0 || mon != 0;
803  bool has_day_time = mday != 0 || hour != 0 ||
804  min != 0 || sec != 0 || fsec != 0;
805  bool has_day = mday != 0;
806  bool sql_standard_value = !(has_negative && has_positive) &&
807  !(has_year_month && has_day_time);
808 
809  /*
810  * SQL Standard wants only 1 "<sign>" preceding the whole
811  * interval ... but can't do that if mixed signs.
812  */
813  if (has_negative && sql_standard_value)
814  {
815  *cp++ = '-';
816  year = -year;
817  mon = -mon;
818  mday = -mday;
819  hour = -hour;
820  min = -min;
821  sec = -sec;
822  fsec = -fsec;
823  }
824 
825  if (!has_negative && !has_positive)
826  {
827  sprintf(cp, "0");
828  }
829  else if (!sql_standard_value)
830  {
831  /*
832  * For non sql-standard interval values, force outputting
833  * the signs to avoid ambiguities with intervals with
834  * mixed sign components.
835  */
836  char year_sign = (year < 0 || mon < 0) ? '-' : '+';
837  char day_sign = (mday < 0) ? '-' : '+';
838  char sec_sign = (hour < 0 || min < 0 ||
839  sec < 0 || fsec < 0) ? '-' : '+';
840 
841  sprintf(cp, "%c%d-%d %c%d %c%d:%02d:",
842  year_sign, abs(year), abs(mon),
843  day_sign, abs(mday),
844  sec_sign, abs(hour), abs(min));
845  cp += strlen(cp);
846  AppendSeconds(cp, sec, fsec, MAX_INTERVAL_PRECISION, true);
847  }
848  else if (has_year_month)
849  {
850  sprintf(cp, "%d-%d", year, mon);
851  }
852  else if (has_day)
853  {
854  sprintf(cp, "%d %d:%02d:", mday, hour, min);
855  cp += strlen(cp);
856  AppendSeconds(cp, sec, fsec, MAX_INTERVAL_PRECISION, true);
857  }
858  else
859  {
860  sprintf(cp, "%d:%02d:", hour, min);
861  cp += strlen(cp);
862  AppendSeconds(cp, sec, fsec, MAX_INTERVAL_PRECISION, true);
863  }
864  }
865  break;
866 
867  /* ISO 8601 "time-intervals by duration only" */
868  case INTSTYLE_ISO_8601:
869  /* special-case zero to avoid printing nothing */
870  if (year == 0 && mon == 0 && mday == 0 &&
871  hour == 0 && min == 0 && sec == 0 && fsec == 0)
872  {
873  sprintf(cp, "PT0S");
874  break;
875  }
876  *cp++ = 'P';
877  cp = AddISO8601IntPart(cp, year, 'Y');
878  cp = AddISO8601IntPart(cp, mon, 'M');
879  cp = AddISO8601IntPart(cp, mday, 'D');
880  if (hour != 0 || min != 0 || sec != 0 || fsec != 0)
881  *cp++ = 'T';
882  cp = AddISO8601IntPart(cp, hour, 'H');
883  cp = AddISO8601IntPart(cp, min, 'M');
884  if (sec != 0 || fsec != 0)
885  {
886  if (sec < 0 || fsec < 0)
887  *cp++ = '-';
888  AppendSeconds(cp, sec, fsec, MAX_INTERVAL_PRECISION, false);
889  cp += strlen(cp);
890  *cp++ = 'S';
891  *cp = '\0';
892  }
893  break;
894 
895  /* Compatible with postgresql < 8.4 when DateStyle = 'iso' */
896  case INTSTYLE_POSTGRES:
897  cp = AddPostgresIntPart(cp, year, "year", &is_zero, &is_before);
898  cp = AddPostgresIntPart(cp, mon, "mon", &is_zero, &is_before);
899  cp = AddPostgresIntPart(cp, mday, "day", &is_zero, &is_before);
900  if (is_zero || hour != 0 || min != 0 || sec != 0 || fsec != 0)
901  {
902  bool minus = (hour < 0 || min < 0 || sec < 0 || fsec < 0);
903 
904  sprintf(cp, "%s%s%02d:%02d:",
905  is_zero ? "" : " ",
906  (minus ? "-" : (is_before ? "+" : "")),
907  abs(hour), abs(min));
908  cp += strlen(cp);
909  AppendSeconds(cp, sec, fsec, MAX_INTERVAL_PRECISION, true);
910  }
911  break;
912 
913  /* Compatible with postgresql < 8.4 when DateStyle != 'iso' */
915  default:
916  strcpy(cp, "@");
917  cp++;
918  cp = AddVerboseIntPart(cp, year, "year", &is_zero, &is_before);
919  cp = AddVerboseIntPart(cp, mon, "mon", &is_zero, &is_before);
920  cp = AddVerboseIntPart(cp, mday, "day", &is_zero, &is_before);
921  cp = AddVerboseIntPart(cp, hour, "hour", &is_zero, &is_before);
922  cp = AddVerboseIntPart(cp, min, "min", &is_zero, &is_before);
923  if (sec != 0 || fsec != 0)
924  {
925  *cp++ = ' ';
926  if (sec < 0 || (sec == 0 && fsec < 0))
927  {
928  if (is_zero)
929  is_before = true;
930  else if (!is_before)
931  *cp++ = '-';
932  }
933  else if (is_before)
934  *cp++ = '-';
935  AppendSeconds(cp, sec, fsec, MAX_INTERVAL_PRECISION, false);
936  cp += strlen(cp);
937  sprintf(cp, " sec%s",
938  (abs(sec) != 1 || fsec != 0) ? "s" : "");
939  is_zero = false;
940  }
941  /* identically zero? then put in a unitless zero... */
942  if (is_zero)
943  strcat(cp, " 0");
944  if (is_before)
945  strcat(cp, " ago");
946  break;
947  }
948 }
#define INTSTYLE_POSTGRES_VERBOSE
Definition: miscadmin.h:232
static void AppendSeconds(char *cp, int sec, fsec_t fsec, int precision, bool fillzeros)
Definition: interval.c:747
int tm_hour
Definition: pgtime.h:29
static struct pg_tm tm
Definition: localtime.c:107
#define MAX_INTERVAL_PRECISION
Definition: timestamp.h:54
static char * AddISO8601IntPart(char *cp, int value, char units)
Definition: interval.c:737
int tm_mday
Definition: pgtime.h:30
int tm_mon
Definition: pgtime.h:31
#define INTSTYLE_ISO_8601
Definition: miscadmin.h:234
static char * AddPostgresIntPart(char *cp, int value, const char *units, bool *is_zero, bool *is_before)
Definition: interval.c:714
#define INTSTYLE_SQL_STANDARD
Definition: miscadmin.h:233
int tm_year
Definition: pgtime.h:32
int tm_sec
Definition: pgtime.h:27
int tm_min
Definition: pgtime.h:28
static char * AddVerboseIntPart(char *cp, int value, const char *units, bool *is_zero, bool *is_before)
Definition: interval.c:694
#define INTSTYLE_POSTGRES
Definition: miscadmin.h:231

◆ GetCurrentDateTime()

void GetCurrentDateTime ( struct tm )

Definition at line 1062 of file dt_common.c.

References abstime2tm().

Referenced by DecodeDateTime().

1063 {
1064  int tz;
1065 
1066  abstime2tm(time(NULL), &tz, tm, NULL);
1067 }
static struct pg_tm tm
Definition: localtime.c:107
static void abstime2tm(AbsoluteTime _time, int *tzp, struct tm *tm, char **tzn)
Definition: dt_common.c:977

◆ GetEpochTime()

int GetEpochTime ( struct tm )

Definition at line 954 of file dt_common.c.

References epoch.

955 {
956  struct tm *t0;
957  time_t epoch = 0;
958 
959  t0 = gmtime(&epoch);
960 
961  if (t0)
962  {
963  tm->tm_year = t0->tm_year + 1900;
964  tm->tm_mon = t0->tm_mon + 1;
965  tm->tm_mday = t0->tm_mday;
966  tm->tm_hour = t0->tm_hour;
967  tm->tm_min = t0->tm_min;
968  tm->tm_sec = t0->tm_sec;
969 
970  return 0;
971  }
972 
973  return -1;
974 } /* GetEpochTime() */
int tm_hour
Definition: pgtime.h:29
static struct pg_tm tm
Definition: localtime.c:107
int tm_mday
Definition: pgtime.h:30
int tm_mon
Definition: pgtime.h:31
int tm_year
Definition: pgtime.h:32
static const unsigned __int64 epoch
Definition: gettimeofday.c:34
int tm_sec
Definition: pgtime.h:27
int tm_min
Definition: pgtime.h:28

◆ j2date()

void j2date ( int  ,
int *  ,
int *  ,
int *   
)

Definition at line 317 of file datetime.c.

References MONTHS_PER_YEAR.

Referenced by date2timestamptz(), date_out(), datum_to_json(), datum_to_jsonb(), DecodeDateTime(), DecodeNumber(), DecodeTimeOnly(), do_to_timestamp(), isoweek2date(), isoweekdate2date(), map_sql_value_to_xml_value(), PGTYPESdate_fmt_asc(), PGTYPESdate_julmdy(), PGTYPESdate_to_asc(), timestamp2tm(), timestamp_pl_interval(), timestamptz_pl_interval(), and ValidateDate().

318 {
319  unsigned int julian;
320  unsigned int quad;
321  unsigned int extra;
322  int y;
323 
324  julian = jd;
325  julian += 32044;
326  quad = julian / 146097;
327  extra = (julian - quad * 146097) * 4 + 3;
328  julian += 60 + quad * 3 + extra / 146097;
329  quad = julian / 1461;
330  julian -= quad * 1461;
331  y = julian * 4 / 1461;
332  julian = ((y != 0) ? ((julian + 305) % 365) : ((julian + 306) % 366))
333  + 123;
334  y += quad * 4;
335  *year = y - 4800;
336  quad = julian * 2141 / 65536;
337  *day = julian - 7834 * quad / 256;
338  *month = (quad + 10) % MONTHS_PER_YEAR + 1;
339 
340  return;
341 } /* j2date() */
#define MONTHS_PER_YEAR
Definition: timestamp.h:69

◆ ParseDateTime()

int ParseDateTime ( char *  ,
char *  ,
char **  ,
int *  ,
int *  ,
char **   
)

Definition at line 1602 of file dt_common.c.

References DTK_DATE, DTK_NUMBER, DTK_SPECIAL, DTK_STRING, DTK_TIME, DTK_TZ, MAXDATEFIELDS, and pg_tolower().

1604 {
1605  int nf = 0;
1606  char *lp = lowstr;
1607 
1608  *endstr = timestr;
1609  /* outer loop through fields */
1610  while (*(*endstr) != '\0')
1611  {
1612  /* Record start of current field */
1613  if (nf >= MAXDATEFIELDS)
1614  return -1;
1615  field[nf] = lp;
1616 
1617  /* leading digit? then date or time */
1618  if (isdigit((unsigned char) *(*endstr)))
1619  {
1620  *lp++ = *(*endstr)++;
1621  while (isdigit((unsigned char) *(*endstr)))
1622  *lp++ = *(*endstr)++;
1623 
1624  /* time field? */
1625  if (*(*endstr) == ':')
1626  {
1627  ftype[nf] = DTK_TIME;
1628  *lp++ = *(*endstr)++;
1629  while (isdigit((unsigned char) *(*endstr)) ||
1630  (*(*endstr) == ':') || (*(*endstr) == '.'))
1631  *lp++ = *(*endstr)++;
1632  }
1633  /* date field? allow embedded text month */
1634  else if (*(*endstr) == '-' || *(*endstr) == '/' || *(*endstr) == '.')
1635  {
1636  /* save delimiting character to use later */
1637  char *dp = (*endstr);
1638 
1639  *lp++ = *(*endstr)++;
1640  /* second field is all digits? then no embedded text month */
1641  if (isdigit((unsigned char) *(*endstr)))
1642  {
1643  ftype[nf] = (*dp == '.') ? DTK_NUMBER : DTK_DATE;
1644  while (isdigit((unsigned char) *(*endstr)))
1645  *lp++ = *(*endstr)++;
1646 
1647  /*
1648  * insist that the delimiters match to get a three-field
1649  * date.
1650  */
1651  if (*(*endstr) == *dp)
1652  {
1653  ftype[nf] = DTK_DATE;
1654  *lp++ = *(*endstr)++;
1655  while (isdigit((unsigned char) *(*endstr)) || (*(*endstr) == *dp))
1656  *lp++ = *(*endstr)++;
1657  }
1658  }
1659  else
1660  {
1661  ftype[nf] = DTK_DATE;
1662  while (isalnum((unsigned char) *(*endstr)) || (*(*endstr) == *dp))
1663  *lp++ = pg_tolower((unsigned char) *(*endstr)++);
1664  }
1665  }
1666 
1667  /*
1668  * otherwise, number only and will determine year, month, day, or
1669  * concatenated fields later...
1670  */
1671  else
1672  ftype[nf] = DTK_NUMBER;
1673  }
1674  /* Leading decimal point? Then fractional seconds... */
1675  else if (*(*endstr) == '.')
1676  {
1677  *lp++ = *(*endstr)++;
1678  while (isdigit((unsigned char) *(*endstr)))
1679  *lp++ = *(*endstr)++;
1680 
1681  ftype[nf] = DTK_NUMBER;
1682  }
1683 
1684  /*
1685  * text? then date string, month, day of week, special, or timezone
1686  */
1687  else if (isalpha((unsigned char) *(*endstr)))
1688  {
1689  ftype[nf] = DTK_STRING;
1690  *lp++ = pg_tolower((unsigned char) *(*endstr)++);
1691  while (isalpha((unsigned char) *(*endstr)))
1692  *lp++ = pg_tolower((unsigned char) *(*endstr)++);
1693 
1694  /*
1695  * Full date string with leading text month? Could also be a POSIX
1696  * time zone...
1697  */
1698  if (*(*endstr) == '-' || *(*endstr) == '/' || *(*endstr) == '.')
1699  {
1700  char *dp = (*endstr);
1701 
1702  ftype[nf] = DTK_DATE;
1703  *lp++ = *(*endstr)++;
1704  while (isdigit((unsigned char) *(*endstr)) || *(*endstr) == *dp)
1705  *lp++ = *(*endstr)++;
1706  }
1707  }
1708  /* skip leading spaces */
1709  else if (isspace((unsigned char) *(*endstr)))
1710  {
1711  (*endstr)++;
1712  continue;
1713  }
1714  /* sign? then special or numeric timezone */
1715  else if (*(*endstr) == '+' || *(*endstr) == '-')
1716  {
1717  *lp++ = *(*endstr)++;
1718  /* soak up leading whitespace */
1719  while (isspace((unsigned char) *(*endstr)))
1720  (*endstr)++;
1721  /* numeric timezone? */
1722  if (isdigit((unsigned char) *(*endstr)))
1723  {
1724  ftype[nf] = DTK_TZ;
1725  *lp++ = *(*endstr)++;
1726  while (isdigit((unsigned char) *(*endstr)) ||
1727  (*(*endstr) == ':') || (*(*endstr) == '.'))
1728  *lp++ = *(*endstr)++;
1729  }
1730  /* special? */
1731  else if (isalpha((unsigned char) *(*endstr)))
1732  {
1733  ftype[nf] = DTK_SPECIAL;
1734  *lp++ = pg_tolower((unsigned char) *(*endstr)++);
1735  while (isalpha((unsigned char) *(*endstr)))
1736  *lp++ = pg_tolower((unsigned char) *(*endstr)++);
1737  }
1738  /* otherwise something wrong... */
1739  else
1740  return -1;
1741  }
1742  /* ignore punctuation but use as delimiter */
1743  else if (ispunct((unsigned char) *(*endstr)))
1744  {
1745  (*endstr)++;
1746  continue;
1747 
1748  }
1749  /* otherwise, something is not right... */
1750  else
1751  return -1;
1752 
1753  /* force in a delimiter after each field */
1754  *lp++ = '\0';
1755  nf++;
1756  }
1757 
1758  *numfields = nf;
1759 
1760  return 0;
1761 } /* ParseDateTime() */
unsigned char pg_tolower(unsigned char ch)
Definition: pgstrcasecmp.c:122
#define DTK_TZ
Definition: datetime.h:147
#define DTK_NUMBER
Definition: datetime.h:142
#define DTK_TIME
Definition: datetime.h:146
#define MAXDATEFIELDS
Definition: datetime.h:205
#define DTK_STRING
Definition: datetime.h:143
#define DTK_DATE
Definition: datetime.h:145
#define DTK_SPECIAL
Definition: datetime.h:150

◆ PGTYPEStimestamp_defmt_scan()

int PGTYPEStimestamp_defmt_scan ( char **  str,
char *  fmt,
timestamp d,
int *  year,
int *  month,
int *  day,
int *  hour,
int *  minute,
int *  second,
int *  tz 
)

Definition at line 2524 of file dt_common.c.

References day_tab, days, DecodeTimezone(), DTZ, free, isleap, un_fmt_comb::luint_val, months, MONTHS_PER_YEAR, pg_strcasecmp(), pgtypes_alloc(), pgtypes_date_months, pgtypes_date_weekdays_short, pgtypes_defmt_scan(), PGTYPES_TYPE_STRING_MALLOCED, PGTYPES_TYPE_UINT, PGTYPES_TYPE_UINT_LONG, generate_unaccent_rules::str, un_fmt_comb::str_val, szdatetktbl, tm, tm2timestamp(), generate_unaccent_rules::type, TZ, un_fmt_comb::uint_val, and datetkn::value.

Referenced by PGTYPEStimestamp_defmt_asc().

2528 {
2529  union un_fmt_comb scan_val;
2530  int scan_type;
2531 
2532  char *pstr,
2533  *pfmt,
2534  *tmp;
2535  int err = 1;
2536  unsigned int j;
2537  struct tm tm;
2538 
2539  pfmt = fmt;
2540  pstr = *str;
2541 
2542  while (*pfmt)
2543  {
2544  err = 0;
2545  while (*pfmt == ' ')
2546  pfmt++;
2547  while (*pstr == ' ')
2548  pstr++;
2549  if (*pfmt != '%')
2550  {
2551  if (*pfmt == *pstr)
2552  {
2553  pfmt++;
2554  pstr++;
2555  }
2556  else
2557  {
2558  /* Error: no match */
2559  err = 1;
2560  return err;
2561  }
2562  continue;
2563  }
2564  /* here *pfmt equals '%' */
2565  pfmt++;
2566  switch (*pfmt)
2567  {
2568  case 'a':
2569  pfmt++;
2570 
2571  /*
2572  * we parse the day and see if it is a week day but we do not
2573  * check if the week day really matches the date
2574  */
2575  err = 1;
2576  j = 0;
2577  while (pgtypes_date_weekdays_short[j])
2578  {
2579  if (strncmp(pgtypes_date_weekdays_short[j], pstr,
2580  strlen(pgtypes_date_weekdays_short[j])) == 0)
2581  {
2582  /* found it */
2583  err = 0;
2584  pstr += strlen(pgtypes_date_weekdays_short[j]);
2585  break;
2586  }
2587  j++;
2588  }
2589  break;
2590  case 'A':
2591  /* see note above */
2592  pfmt++;
2593  err = 1;
2594  j = 0;
2595  while (days[j])
2596  {
2597  if (strncmp(days[j], pstr, strlen(days[j])) == 0)
2598  {
2599  /* found it */
2600  err = 0;
2601  pstr += strlen(days[j]);
2602  break;
2603  }
2604  j++;
2605  }
2606  break;
2607  case 'b':
2608  case 'h':
2609  pfmt++;
2610  err = 1;
2611  j = 0;
2612  while (months[j])
2613  {
2614  if (strncmp(months[j], pstr, strlen(months[j])) == 0)
2615  {
2616  /* found it */
2617  err = 0;
2618  pstr += strlen(months[j]);
2619  *month = j + 1;
2620  break;
2621  }
2622  j++;
2623  }
2624  break;
2625  case 'B':
2626  /* see note above */
2627  pfmt++;
2628  err = 1;
2629  j = 0;
2630  while (pgtypes_date_months[j])
2631  {
2632  if (strncmp(pgtypes_date_months[j], pstr, strlen(pgtypes_date_months[j])) == 0)
2633  {
2634  /* found it */
2635  err = 0;
2636  pstr += strlen(pgtypes_date_months[j]);
2637  *month = j + 1;
2638  break;
2639  }
2640  j++;
2641  }
2642  break;
2643  case 'c':
2644  /* XXX */
2645  break;
2646  case 'C':
2647  pfmt++;
2648  scan_type = PGTYPES_TYPE_UINT;
2649  err = pgtypes_defmt_scan(&scan_val, scan_type, &pstr, pfmt);
2650  *year = scan_val.uint_val * 100;
2651  break;
2652  case 'd':
2653  case 'e':
2654  pfmt++;
2655  scan_type = PGTYPES_TYPE_UINT;
2656  err = pgtypes_defmt_scan(&scan_val, scan_type, &pstr, pfmt);
2657  *day = scan_val.uint_val;
2658  break;
2659  case 'D':
2660 
2661  /*
2662  * we have to concatenate the strings in order to be able to
2663  * find the end of the substitution
2664  */
2665  pfmt++;
2666  tmp = pgtypes_alloc(strlen("%m/%d/%y") + strlen(pstr) + 1);
2667  strcpy(tmp, "%m/%d/%y");
2668  strcat(tmp, pfmt);
2669  err = PGTYPEStimestamp_defmt_scan(&pstr, tmp, d, year, month, day, hour, minute, second, tz);
2670  free(tmp);
2671  return err;
2672  case 'm':
2673  pfmt++;
2674  scan_type = PGTYPES_TYPE_UINT;
2675  err = pgtypes_defmt_scan(&scan_val, scan_type, &pstr, pfmt);
2676  *month = scan_val.uint_val;
2677  break;
2678  case 'y':
2679  case 'g': /* XXX difference to y (ISO) */
2680  pfmt++;
2681  scan_type = PGTYPES_TYPE_UINT;
2682  err = pgtypes_defmt_scan(&scan_val, scan_type, &pstr, pfmt);
2683  if (*year < 0)
2684  {
2685  /* not yet set */
2686  *year = scan_val.uint_val;
2687  }
2688  else
2689  *year += scan_val.uint_val;
2690  if (*year < 100)
2691  *year += 1900;
2692  break;
2693  case 'G':
2694  /* XXX difference to %V (ISO) */
2695  pfmt++;
2696  scan_type = PGTYPES_TYPE_UINT;
2697  err = pgtypes_defmt_scan(&scan_val, scan_type, &pstr, pfmt);
2698  *year = scan_val.uint_val;
2699  break;
2700  case 'H':
2701  case 'I':
2702  case 'k':
2703  case 'l':
2704  pfmt++;
2705  scan_type = PGTYPES_TYPE_UINT;
2706  err = pgtypes_defmt_scan(&scan_val, scan_type, &pstr, pfmt);
2707  *hour += scan_val.uint_val;
2708  break;
2709  case 'j':
2710  pfmt++;
2711  scan_type = PGTYPES_TYPE_UINT;
2712  err = pgtypes_defmt_scan(&scan_val, scan_type, &pstr, pfmt);
2713 
2714  /*
2715  * XXX what should we do with that? We could say that it's
2716  * sufficient if we have the year and the day within the year
2717  * to get at least a specific day.
2718  */
2719  break;
2720  case 'M':
2721  pfmt++;
2722  scan_type = PGTYPES_TYPE_UINT;
2723  err = pgtypes_defmt_scan(&scan_val, scan_type, &pstr, pfmt);
2724  *minute = scan_val.uint_val;
2725  break;
2726  case 'n':
2727  pfmt++;
2728  if (*pstr == '\n')
2729  pstr++;
2730  else
2731  err = 1;
2732  break;
2733  case 'p':
2734  err = 1;
2735  pfmt++;
2736  if (strncmp(pstr, "am", 2) == 0)
2737  {
2738  *hour += 0;
2739  err = 0;
2740  pstr += 2;
2741  }
2742  if (strncmp(pstr, "a.m.", 4) == 0)
2743  {
2744  *hour += 0;
2745  err = 0;
2746  pstr += 4;
2747  }
2748  if (strncmp(pstr, "pm", 2) == 0)
2749  {
2750  *hour += 12;
2751  err = 0;
2752  pstr += 2;
2753  }
2754  if (strncmp(pstr, "p.m.", 4) == 0)
2755  {
2756  *hour += 12;
2757  err = 0;
2758  pstr += 4;
2759  }
2760  break;
2761  case 'P':
2762  err = 1;
2763  pfmt++;
2764  if (strncmp(pstr, "AM", 2) == 0)
2765  {
2766  *hour += 0;
2767  err = 0;
2768  pstr += 2;
2769  }
2770  if (strncmp(pstr, "A.M.", 4) == 0)
2771  {
2772  *hour += 0;
2773  err = 0;
2774  pstr += 4;
2775  }
2776  if (strncmp(pstr, "PM", 2) == 0)
2777  {
2778  *hour += 12;
2779  err = 0;
2780  pstr += 2;
2781  }
2782  if (strncmp(pstr, "P.M.", 4) == 0)
2783  {
2784  *hour += 12;
2785  err = 0;
2786  pstr += 4;
2787  }
2788  break;
2789  case 'r':
2790  pfmt++;
2791  tmp = pgtypes_alloc(strlen("%I:%M:%S %p") + strlen(pstr) + 1);
2792  strcpy(tmp, "%I:%M:%S %p");
2793  strcat(tmp, pfmt);
2794  err = PGTYPEStimestamp_defmt_scan(&pstr, tmp, d, year, month, day, hour, minute, second, tz);
2795  free(tmp);
2796  return err;
2797  case 'R':
2798  pfmt++;
2799  tmp = pgtypes_alloc(strlen("%H:%M") + strlen(pstr) + 1);
2800  strcpy(tmp, "%H:%M");
2801  strcat(tmp, pfmt);
2802  err = PGTYPEStimestamp_defmt_scan(&pstr, tmp, d, year, month, day, hour, minute, second, tz);
2803  free(tmp);
2804  return err;
2805  case 's':
2806  pfmt++;
2807  scan_type = PGTYPES_TYPE_UINT_LONG;
2808  err = pgtypes_defmt_scan(&scan_val, scan_type, &pstr, pfmt);
2809  /* number of seconds in scan_val.luint_val */
2810  {
2811  struct tm *tms;
2812  time_t et = (time_t) scan_val.luint_val;
2813 
2814  tms = gmtime(&et);
2815 
2816  if (tms)
2817  {
2818  *year = tms->tm_year + 1900;
2819  *month = tms->tm_mon + 1;
2820  *day = tms->tm_mday;
2821  *hour = tms->tm_hour;
2822  *minute = tms->tm_min;
2823  *second = tms->tm_sec;
2824  }
2825  else
2826  err = 1;
2827  }
2828  break;
2829  case 'S':
2830  pfmt++;
2831  scan_type = PGTYPES_TYPE_UINT;
2832  err = pgtypes_defmt_scan(&scan_val, scan_type, &pstr, pfmt);
2833  *second = scan_val.uint_val;
2834  break;
2835  case 't':
2836  pfmt++;
2837  if (*pstr == '\t')
2838  pstr++;
2839  else
2840  err = 1;
2841  break;
2842  case 'T':
2843  pfmt++;
2844  tmp = pgtypes_alloc(strlen("%H:%M:%S") + strlen(pstr) + 1);
2845  strcpy(tmp, "%H:%M:%S");
2846  strcat(tmp, pfmt);
2847  err = PGTYPEStimestamp_defmt_scan(&pstr, tmp, d, year, month, day, hour, minute, second, tz);
2848  free(tmp);
2849  return err;
2850  case 'u':
2851  pfmt++;
2852  scan_type = PGTYPES_TYPE_UINT;
2853  err = pgtypes_defmt_scan(&scan_val, scan_type, &pstr, pfmt);
2854  if (scan_val.uint_val < 1 || scan_val.uint_val > 7)
2855  err = 1;
2856  break;
2857  case 'U':
2858  pfmt++;
2859  scan_type = PGTYPES_TYPE_UINT;
2860  err = pgtypes_defmt_scan(&scan_val, scan_type, &pstr, pfmt);
2861  if (scan_val.uint_val > 53)
2862  err = 1;
2863  break;
2864  case 'V':
2865  pfmt++;
2866  scan_type = PGTYPES_TYPE_UINT;
2867  err = pgtypes_defmt_scan(&scan_val, scan_type, &pstr, pfmt);
2868  if (scan_val.uint_val < 1 || scan_val.uint_val > 53)
2869  err = 1;
2870  break;
2871  case 'w':
2872  pfmt++;
2873  scan_type = PGTYPES_TYPE_UINT;
2874  err = pgtypes_defmt_scan(&scan_val, scan_type, &pstr, pfmt);
2875  if (scan_val.uint_val > 6)
2876  err = 1;
2877  break;
2878  case 'W':
2879  pfmt++;
2880  scan_type = PGTYPES_TYPE_UINT;
2881  err = pgtypes_defmt_scan(&scan_val, scan_type, &pstr, pfmt);
2882  if (scan_val.uint_val > 53)
2883  err = 1;
2884  break;
2885  case 'x':
2886  case 'X':
2887  /* XXX */
2888  break;
2889  case 'Y':
2890  pfmt++;
2891  scan_type = PGTYPES_TYPE_UINT;
2892  err = pgtypes_defmt_scan(&scan_val, scan_type, &pstr, pfmt);
2893  *year = scan_val.uint_val;
2894  break;
2895  case 'z':
2896  pfmt++;
2897  scan_type = PGTYPES_TYPE_STRING_MALLOCED;
2898  err = pgtypes_defmt_scan(&scan_val, scan_type, &pstr, pfmt);
2899  if (!err)
2900  {
2901  err = DecodeTimezone(scan_val.str_val, tz);
2902  free(scan_val.str_val);
2903  }
2904  break;
2905  case 'Z':
2906  pfmt++;
2907  scan_type = PGTYPES_TYPE_STRING_MALLOCED;
2908  err = pgtypes_defmt_scan(&scan_val, scan_type, &pstr, pfmt);
2909  if (!err)
2910  {
2911  /*
2912  * XXX use DecodeSpecial instead? Do we need strcasecmp
2913  * here?
2914  */
2915  err = 1;
2916  for (j = 0; j < szdatetktbl; j++)
2917  {
2918  if ((datetktbl[j].type == TZ || datetktbl[j].type == DTZ) &&
2919  pg_strcasecmp(datetktbl[j].token,
2920  scan_val.str_val) == 0)
2921  {
2922  *tz = -datetktbl[j].value;
2923  err = 0;
2924  break;
2925  }
2926  }
2927  free(scan_val.str_val);
2928  }
2929  break;
2930  case '+':
2931  /* XXX */
2932  break;
2933  case '%':
2934  pfmt++;
2935  if (*pstr == '%')
2936  pstr++;
2937  else
2938  err = 1;
2939  break;
2940  default:
2941  err = 1;
2942  }
2943  }
2944  if (!err)
2945  {
2946  if (*second < 0)
2947  *second = 0;
2948  if (*minute < 0)
2949  *minute = 0;
2950  if (*hour < 0)
2951  *hour = 0;
2952  if (*day < 0)
2953  {
2954  err = 1;
2955  *day = 1;
2956  }
2957  if (*month < 0)
2958  {
2959  err = 1;
2960  *month = 1;
2961  }
2962  if (*year < 0)
2963  {
2964  err = 1;
2965  *year = 1970;
2966  }
2967 
2968  if (*second > 59)
2969  {
2970  err = 1;
2971  *second = 0;
2972  }
2973  if (*minute > 59)
2974  {
2975  err = 1;
2976  *minute = 0;
2977  }
2978  if (*hour > 24 || /* test for > 24:00:00 */
2979  (*hour == 24 && (*minute > 0 || *second > 0)))
2980  {
2981  err = 1;
2982  *hour = 0;
2983  }
2984  if (*month > MONTHS_PER_YEAR)
2985  {
2986  err = 1;
2987  *month = 1;
2988  }
2989  if (*day > day_tab[isleap(*year)][*month - 1])
2990  {
2991  *day = day_tab[isleap(*year)][*month - 1];
2992  err = 1;
2993  }
2994 
2995  tm.tm_sec = *second;
2996  tm.tm_min = *minute;
2997  tm.tm_hour = *hour;
2998  tm.tm_mday = *day;
2999  tm.tm_mon = *month;
3000  tm.tm_year = *year;
3001 
3002  tm2timestamp(&tm, 0, tz, d);
3003  }
3004  return err;
3005 }
#define PGTYPES_TYPE_STRING_MALLOCED
Definition: extern.h:11
static const unsigned int szdatetktbl
Definition: dt_common.c:490
char * days[]
Definition: dt_common.c:499
int tm_hour
Definition: pgtime.h:29
#define isleap(y)
Definition: datetime.h:273
#define TZ
Definition: datetime.h:96
int32 value
Definition: datetime.h:214
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:36
static int DecodeTimezone(char *str, int *tzp)
Definition: dt_common.c:1504
static struct pg_tm tm
Definition: localtime.c:107
#define MONTHS_PER_YEAR
Definition: timestamp.h:69
char * months[]
Definition: dt_common.c:497
char * pgtypes_alloc(long size)
Definition: common.c:9
int tm_mday
Definition: pgtime.h:30
int PGTYPEStimestamp_defmt_scan(char **str, char *fmt, timestamp *d, int *year, int *month, int *day, int *hour, int *minute, int *second, int *tz)
Definition: dt_common.c:2524
int tm_mon
Definition: pgtime.h:31
int day_tab[2][13]
Definition: dt_common.c:13
char * pgtypes_date_weekdays_short[]
Definition: dt_common.c:501
#define free(a)
Definition: header.h:65
int tm2timestamp(struct pg_tm *tm, fsec_t fsec, int *tzp, Timestamp *result)
Definition: timestamp.c:1854
#define PGTYPES_TYPE_UINT_LONG
Definition: extern.h:22
#define DTZ
Definition: datetime.h:97
int tm_year
Definition: pgtime.h:32
static datetkn datetktbl[]
Definition: dt_common.c:19
int tm_sec
Definition: pgtime.h:27
#define PGTYPES_TYPE_UINT
Definition: extern.h:16
int tm_min
Definition: pgtime.h:28
char * pgtypes_date_months[]
Definition: dt_common.c:503
static int pgtypes_defmt_scan(union un_fmt_comb *scan_val, int scan_type, char **pstr, char *pfmt)
Definition: dt_common.c:2462

◆ tm2timestamp()

int tm2timestamp ( struct tm ,
fsec_t  ,
int *  ,
timestamp  
)

Definition at line 42 of file timestamp.c.

References date2j(), dt2local(), IS_VALID_JULIAN, IS_VALID_TIMESTAMP, time2t(), and USECS_PER_DAY.

43 {
44  int dDate;
45  int64 time;
46 
47  /* Prevent overflow in Julian-day routines */
49  return -1;
50 
51  dDate = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - date2j(2000, 1, 1);
52  time = time2t(tm->tm_hour, tm->tm_min, tm->tm_sec, fsec);
53  *result = (dDate * USECS_PER_DAY) + time;
54  /* check for major overflow */
55  if ((*result - time) / USECS_PER_DAY != dDate)
56  return -1;
57  /* check for just-barely overflow (okay except time-of-day wraps) */
58  /* caution: we want to allow 1999-12-31 24:00:00 */
59  if ((*result < 0 && dDate > 0) ||
60  (*result > 0 && dDate < -1))
61  return -1;
62  if (tzp != NULL)
63  *result = dt2local(*result, -(*tzp));
64 
65  /* final range check catches just-out-of-range timestamps */
66  if (!IS_VALID_TIMESTAMP(*result))
67  return -1;
68 
69  return 0;
70 } /* tm2timestamp() */
static int64 time2t(const int hour, const int min, const int sec, const fsec_t fsec)
Definition: timestamp.c:22
int tm_hour
Definition: pgtime.h:29
static timestamp dt2local(timestamp dt, int tz)
Definition: timestamp.c:28
static struct pg_tm tm
Definition: localtime.c:107
int tm_mday
Definition: pgtime.h:30
int tm_mon
Definition: pgtime.h:31
#define IS_VALID_JULIAN(y, m, d)
Definition: timestamp.h:155
#define USECS_PER_DAY
Definition: timestamp.h:91
int date2j(int y, int m, int d)
Definition: datetime.c:292
#define IS_VALID_TIMESTAMP(t)
Definition: timestamp.h:195
int tm_year
Definition: pgtime.h:32
int tm_sec
Definition: pgtime.h:27
int tm_min
Definition: pgtime.h:28

◆ TrimTrailingZeros()

void TrimTrailingZeros ( char *  )

Definition at line 728 of file dt_common.c.

Referenced by AppendSeconds(), and EncodeDateTime().

729 {
730  int len = strlen(str);
731 
732  /* chop off trailing zeros... but leave at least 2 fractional digits */
733  while (*(str + len - 1) == '0' && *(str + len - 3) != '.')
734  {
735  len--;
736  *(str + len) = '\0';
737  }
738 }

Variable Documentation

◆ day_tab

◆ days

◆ months

◆ pgtypes_date_months

char* pgtypes_date_months[]

◆ pgtypes_date_weekdays_short

char* pgtypes_date_weekdays_short[]