PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
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 *)
 
int EncodeDateTime (struct tm *tm, fsec_t fsec, bool print_tz, int tz, const char *tzn, int style, char *str, bool EuroDates)
 
int 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)
 
int 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

#define ABS_AFTER   21

Definition at line 112 of file dt.h.

#define ABS_BEFORE   20

Definition at line 111 of file dt.h.

#define AD   0

Definition at line 73 of file dt.h.

#define ADBC   18

Definition at line 108 of file dt.h.

#define AGO   19

Definition at line 110 of file dt.h.

#define AM   0

Definition at line 69 of file dt.h.

#define AMPM   9

Definition at line 99 of file dt.h.

#define BC   1

Definition at line 74 of file dt.h.

#define DA_D   "ad"

Definition at line 58 of file dt.h.

#define DAGO   "ago"

Definition at line 33 of file dt.h.

#define DAY   3

Definition at line 93 of file dt.h.

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

Definition at line 244 of file dt.h.

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

Definition at line 235 of file dt.h.

#define DB_C   "bc"

Definition at line 59 of file dt.h.

#define DCENTURY   "century"

Definition at line 56 of file dt.h.

#define DCURRENT   "current"

Definition at line 34 of file dt.h.

#define DDAY   "day"

Definition at line 50 of file dt.h.

#define DDECADE   "decade"

Definition at line 55 of file dt.h.

#define DHOUR   "hour"

Definition at line 49 of file dt.h.

#define DMICROSEC   "usecond"

Definition at line 45 of file dt.h.

#define DMILLENNIUM   "millennium"

Definition at line 57 of file dt.h.

#define DMILLISEC   "msecond"

Definition at line 46 of file dt.h.

#define DMINUTE   "minute"

Definition at line 48 of file dt.h.

#define DMONTH   "month"

Definition at line 52 of file dt.h.

#define DOW   16

Definition at line 106 of file dt.h.

#define DOY   15

Definition at line 105 of file dt.h.

#define DQUARTER   "quarter"

Definition at line 53 of file dt.h.

#define DSECOND   "second"

Definition at line 47 of file dt.h.

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

Definition at line 305 of file dt.h.

#define DT_NOEND   (INT64CONST(0x7fffffffffffffff))

Definition at line 306 of file dt.h.

#define DTERR_BAD_FORMAT   (-1)

Definition at line 26 of file dt.h.

#define DTERR_FIELD_OVERFLOW   (-2)

Definition at line 27 of file dt.h.

#define DTERR_INTERVAL_OVERFLOW   (-4)

Definition at line 29 of file dt.h.

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

Definition at line 28 of file dt.h.

#define DTERR_TZDISP_OVERFLOW   (-5)

Definition at line 30 of file dt.h.

#define DTIMEZONE   "timezone"

Definition at line 60 of file dt.h.

#define DTK_AGO   5

Definition at line 143 of file dt.h.

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

Definition at line 186 of file dt.h.

#define DTK_CENTURY   27

Definition at line 167 of file dt.h.

#define DTK_CURRENT   8

Definition at line 147 of file dt.h.

#define DTK_DATE   2

Definition at line 140 of file dt.h.

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

Definition at line 187 of file dt.h.

#define DTK_DAY   21

Definition at line 161 of file dt.h.

#define DTK_DECADE   26

Definition at line 166 of file dt.h.

#define DTK_DELTA   17

Definition at line 157 of file dt.h.

#define DTK_DOW   32

Definition at line 173 of file dt.h.

#define DTK_DOY   33

Definition at line 174 of file dt.h.

#define DTK_EARLY   9

Definition at line 148 of file dt.h.

#define DTK_EPOCH   11

Definition at line 150 of file dt.h.

#define DTK_HOUR   20

Definition at line 160 of file dt.h.

#define DTK_INVALID   7

Definition at line 146 of file dt.h.

#define DTK_ISODOW   37

Definition at line 178 of file dt.h.

#define DTK_ISOYEAR   36

Definition at line 177 of file dt.h.

#define DTK_JULIAN   31

Definition at line 171 of file dt.h.

#define DTK_LATE   10

Definition at line 149 of file dt.h.

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

Definition at line 185 of file dt.h.

#define DTK_MICROSEC   30

Definition at line 170 of file dt.h.

#define DTK_MILLENNIUM   28

Definition at line 168 of file dt.h.

#define DTK_MILLISEC   29

Definition at line 169 of file dt.h.

#define DTK_MINUTE   19

Definition at line 159 of file dt.h.

#define DTK_MONTH   23

Definition at line 163 of file dt.h.

#define DTK_NOW   12

Definition at line 151 of file dt.h.

#define DTK_NUMBER   0

Definition at line 137 of file dt.h.

#define DTK_QUARTER   24

Definition at line 164 of file dt.h.

#define DTK_SECOND   18

Definition at line 158 of file dt.h.

#define DTK_SPECIAL   6

Definition at line 145 of file dt.h.

#define DTK_STRING   1

Definition at line 138 of file dt.h.

#define DTK_TIME   3

Definition at line 141 of file dt.h.

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

Definition at line 188 of file dt.h.

#define DTK_TODAY   14

Definition at line 153 of file dt.h.

#define DTK_TOMORROW   15

Definition at line 154 of file dt.h.

#define DTK_TZ   4

Definition at line 142 of file dt.h.

#define DTK_TZ_HOUR   34

Definition at line 175 of file dt.h.

#define DTK_TZ_MINUTE   35

Definition at line 176 of file dt.h.

#define DTK_WEEK   22

Definition at line 162 of file dt.h.

#define DTK_YEAR   25

Definition at line 165 of file dt.h.

#define DTK_YESTERDAY   13

Definition at line 152 of file dt.h.

#define DTK_ZULU   16

Definition at line 155 of file dt.h.

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

Definition at line 96 of file dt.h.

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

Definition at line 117 of file dt.h.

#define DWEEK   "week"

Definition at line 51 of file dt.h.

#define DYEAR   "year"

Definition at line 54 of file dt.h.

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

Definition at line 97 of file dt.h.

#define EARLY   "-infinity"

Definition at line 37 of file dt.h.

#define END_TIMESTAMP   INT64CONST(9223371331200000000)

Definition at line 287 of file dt.h.

#define EPOCH   "epoch"

Definition at line 35 of file dt.h.

#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.

#define HOUR   10

Definition at line 100 of file dt.h.

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

Definition at line 245 of file dt.h.

#define HR24   2

Definition at line 71 of file dt.h.

#define IGNORE_DTF   8

Definition at line 98 of file dt.h.

#define INTERVAL_FULL_RANGE   (0x7FFF)

Definition at line 22 of file dt.h.

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

Definition at line 23 of file dt.h.

#define INTSTYLE_ISO_8601   3

Definition at line 20 of file dt.h.

#define INTSTYLE_POSTGRES   0

Definition at line 17 of file dt.h.

#define INTSTYLE_POSTGRES_VERBOSE   1

Definition at line 18 of file dt.h.

#define INTSTYLE_SQL_STANDARD   2

Definition at line 19 of file dt.h.

#define INVALID   "invalid"

Definition at line 36 of file dt.h.

#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.

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

Definition at line 289 of file dt.h.

#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().

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

Definition at line 267 of file dt.h.

#define ISODATE   22

Definition at line 114 of file dt.h.

#define ISOTIME   23

Definition at line 115 of file dt.h.

#define JULIAN   4

Definition at line 94 of file dt.h.

#define JULIAN_MAXDAY   (3)

Definition at line 278 of file dt.h.

#define JULIAN_MAXMONTH   (6)

Definition at line 277 of file dt.h.

#define JULIAN_MAXYEAR   (5874898)

Definition at line 276 of file dt.h.

#define JULIAN_MINDAY   (24)

Definition at line 275 of file dt.h.

#define JULIAN_MINMONTH   (11)

Definition at line 274 of file dt.h.

#define JULIAN_MINYEAR   (-4713)

Definition at line 273 of file dt.h.

#define LATE   "infinity"

Definition at line 38 of file dt.h.

#define MAX_INTERVAL_PRECISION   6

Definition at line 24 of file dt.h.

#define MAXDATEFIELDS   25

Definition at line 198 of file dt.h.

#define MAXDATELEN   128

Definition at line 196 of file dt.h.

#define MAXTZLEN   10

Definition at line 8 of file dt.h.

#define MICROSECOND   14

Definition at line 104 of file dt.h.

#define MILLISECOND   13

Definition at line 103 of file dt.h.

#define MIN_TIMESTAMP   INT64CONST(-211813488000000000)

Definition at line 286 of file dt.h.

#define MINS_PER_HOUR   60

Definition at line 256 of file dt.h.

#define MINUTE   11

Definition at line 101 of file dt.h.

#define MONTH   1

Definition at line 91 of file dt.h.

#define MONTHS_PER_YEAR   12

Definition at line 236 of file dt.h.

#define NOW   "now"

Definition at line 39 of file dt.h.

#define PM   1

Definition at line 70 of file dt.h.

#define RESERV   0

Definition at line 90 of file dt.h.

#define SECOND   12

Definition at line 102 of file dt.h.

#define SECS_PER_DAY   86400

Definition at line 253 of file dt.h.

#define SECS_PER_HOUR   3600

Definition at line 254 of file dt.h.

#define SECS_PER_MINUTE   60

Definition at line 255 of file dt.h.

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

Definition at line 252 of file dt.h.

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

Definition at line 310 of file dt.h.

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

Definition at line 311 of file dt.h.

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

Definition at line 308 of file dt.h.

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

Definition at line 309 of file dt.h.

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

Definition at line 312 of file dt.h.

#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.

#define TODAY   "today"

Definition at line 40 of file dt.h.

#define TOKMAXLEN   10

Definition at line 200 of file dt.h.

#define TOMORROW   "tomorrow"

Definition at line 41 of file dt.h.

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

Definition at line 95 of file dt.h.

#define UNITS   17

Definition at line 107 of file dt.h.

#define UNKNOWN_FIELD   31

Definition at line 119 of file dt.h.

#define USE_GERMAN_DATES   3

Definition at line 15 of file dt.h.

#define USE_ISO_DATES   1

Definition at line 13 of file dt.h.

#define USE_POSTGRES_DATES   0

Definition at line 12 of file dt.h.

#define USE_SQL_DATES   2

Definition at line 14 of file dt.h.

#define USECS_PER_DAY   INT64CONST(86400000000)

Definition at line 258 of file dt.h.

#define USECS_PER_HOUR   INT64CONST(3600000000)

Definition at line 259 of file dt.h.

#define USECS_PER_MINUTE   INT64CONST(60000000)

Definition at line 260 of file dt.h.

#define USECS_PER_SEC   INT64CONST(1000000)

Definition at line 261 of file dt.h.

#define UTIME_MAXDAY   (18)

Definition at line 296 of file dt.h.

#define UTIME_MAXMONTH   (01)

Definition at line 295 of file dt.h.

#define UTIME_MAXYEAR   (2038)

Definition at line 294 of file dt.h.

#define UTIME_MINDAY   (14)

Definition at line 293 of file dt.h.

#define UTIME_MINMONTH   (12)

Definition at line 292 of file dt.h.

#define UTIME_MINYEAR   (1901)

Definition at line 291 of file dt.h.

#define YEAR   2

Definition at line 92 of file dt.h.

#define YESTERDAY   "yesterday"

Definition at line 42 of file dt.h.

#define ZULU   "zulu"

Definition at line 43 of file dt.h.

Typedef Documentation

Definition at line 10 of file dt.h.

Function Documentation

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:675
#define UNIX_EPOCH_JDATE
Definition: timestamp.h:162
#define POSTGRES_EPOCH_JDATE
Definition: timestamp.h:163
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() */
int DecodeDateTime ( char **  ,
int *  ,
int  ,
int *  ,
struct tm ,
fsec_t ,
bool   
)

Definition at line 1790 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, FALSE, GetCurrentDateTime(), HOUR, HR24, i, IGNORE_DTF, isleap, ISOTIME, j2date(), MINUTE, MONTH, NULL, PM, RESERV, SECOND, TRUE, TZ, UNITS, USECS_PER_DAY, val, and YEAR.

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

Definition at line 338 of file interval.c.

References AdjustFractDays(), AdjustFractSeconds(), AGO, 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, FALSE, HOUR, i, IGNORE_DTF, INTERVAL_FULL_RANGE, INTERVAL_MASK, IntervalStyle, INTSTYLE_POSTGRES_VERBOSE, INTSTYLE_SQL_STANDARD, MICROSECOND, MILLISECOND, MINUTE, MONTH, MONTHS_PER_YEAR, NULL, range(), RESERV, rint(), SECOND, SECS_PER_DAY, SECS_PER_HOUR, SECS_PER_MINUTE, strtoint(), TRUE, TZ, UNITS, USECS_PER_SEC, val, and YEAR.

Referenced by PGTYPESinterval_from_asc().

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

Definition at line 1444 of file dt_common.c.

References DTK_TIME_M, i, and USECS_PER_SEC.

Referenced by DecodeDateTime().

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

Definition at line 3728 of file datetime.c.

References datebsearch(), NULL, szdeltatktbl, datetkn::token, TOKMAXLEN, 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 NULL
Definition: c.h:229
#define TOKMAXLEN
Definition: datetime.h:207
long val
Definition: informix.c:689
void dt2time ( double  ,
int *  ,
int *  ,
int *  ,
fsec_t  
)

Definition at line 1075 of file dt_common.c.

References USECS_PER_HOUR, USECS_PER_MINUTE, and USECS_PER_SEC.

Referenced by DecodeDateTime().

1076 {
1077  int64 time;
1078 
1079  time = jd;
1080  *hour = time / USECS_PER_HOUR;
1081  time -= (*hour) * USECS_PER_HOUR;
1082  *min = time / USECS_PER_MINUTE;
1083  time -= (*min) * USECS_PER_MINUTE;
1084  *sec = time / USECS_PER_SEC;
1085  *fsec = time - (*sec * USECS_PER_SEC);
1086 } /* 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
int EncodeDateOnly ( struct tm tm,
int  style,
char *  str,
bool  EuroDates 
)

Definition at line 675 of file dt_common.c.

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

676 {
677  if (tm->tm_mon < 1 || tm->tm_mon > MONTHS_PER_YEAR)
678  return -1;
679 
680  switch (style)
681  {
682  case USE_ISO_DATES:
683  /* compatible with ISO date formats */
684  if (tm->tm_year > 0)
685  sprintf(str, "%04d-%02d-%02d",
686  tm->tm_year, tm->tm_mon, tm->tm_mday);
687  else
688  sprintf(str, "%04d-%02d-%02d %s",
689  -(tm->tm_year - 1), tm->tm_mon, tm->tm_mday, "BC");
690  break;
691 
692  case USE_SQL_DATES:
693  /* compatible with Oracle/Ingres date formats */
694  if (EuroDates)
695  sprintf(str, "%02d/%02d", tm->tm_mday, tm->tm_mon);
696  else
697  sprintf(str, "%02d/%02d", tm->tm_mon, tm->tm_mday);
698  if (tm->tm_year > 0)
699  sprintf(str + 5, "/%04d", tm->tm_year);
700  else
701  sprintf(str + 5, "/%04d %s", -(tm->tm_year - 1), "BC");
702  break;
703 
704  case USE_GERMAN_DATES:
705  /* German-style date format */
706  sprintf(str, "%02d.%02d", tm->tm_mday, tm->tm_mon);
707  if (tm->tm_year > 0)
708  sprintf(str + 5, ".%04d", tm->tm_year);
709  else
710  sprintf(str + 5, ".%04d %s", -(tm->tm_year - 1), "BC");
711  break;
712 
713  case USE_POSTGRES_DATES:
714  default:
715  /* traditional date-only style for Postgres */
716  if (EuroDates)
717  sprintf(str, "%02d-%02d", tm->tm_mday, tm->tm_mon);
718  else
719  sprintf(str, "%02d-%02d", tm->tm_mon, tm->tm_mday);
720  if (tm->tm_year > 0)
721  sprintf(str + 5, "-%04d", tm->tm_year);
722  else
723  sprintf(str + 5, "-%04d %s", -(tm->tm_year - 1), "BC");
724  break;
725  }
726 
727  return TRUE;
728 } /* EncodeDateOnly() */
#define USE_SQL_DATES
Definition: miscadmin.h:214
#define USE_ISO_DATES
Definition: miscadmin.h:213
static struct pg_tm tm
Definition: localtime.c:111
#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:212
int tm_year
Definition: pgtime.h:32
#define USE_GERMAN_DATES
Definition: miscadmin.h:215
#define TRUE
Definition: c.h:217
int EncodeDateTime ( struct tm tm,
fsec_t  fsec,
bool  print_tz,
int  tz,
const char *  tzn,
int  style,
char *  str,
bool  EuroDates 
)

Definition at line 762 of file dt_common.c.

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

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

Definition at line 775 of file interval.c.

References AddISO8601IntPart(), AddPostgresIntPart(), AddVerboseIntPart(), AppendSeconds(), FALSE, INTSTYLE_ISO_8601, INTSTYLE_POSTGRES, INTSTYLE_POSTGRES_VERBOSE, INTSTYLE_SQL_STANDARD, MAX_INTERVAL_PRECISION, and TRUE.

Referenced by PGTYPESinterval_to_asc().

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

Definition at line 1067 of file dt_common.c.

References abstime2tm(), and NULL.

Referenced by DecodeDateTime().

1068 {
1069  int tz;
1070 
1071  abstime2tm(time(NULL), &tz, tm, NULL);
1072 }
static struct pg_tm tm
Definition: localtime.c:111
#define NULL
Definition: c.h:229
static void abstime2tm(AbsoluteTime _time, int *tzp, struct tm *tm, char **tzn)
Definition: dt_common.c:982
int GetEpochTime ( struct tm )

Definition at line 959 of file dt_common.c.

References epoch.

960 {
961  struct tm *t0;
962  time_t epoch = 0;
963 
964  t0 = gmtime(&epoch);
965 
966  if (t0)
967  {
968  tm->tm_year = t0->tm_year + 1900;
969  tm->tm_mon = t0->tm_mon + 1;
970  tm->tm_mday = t0->tm_mday;
971  tm->tm_hour = t0->tm_hour;
972  tm->tm_min = t0->tm_min;
973  tm->tm_sec = t0->tm_sec;
974 
975  return 0;
976  }
977 
978  return -1;
979 } /* GetEpochTime() */
int tm_hour
Definition: pgtime.h:29
static struct pg_tm tm
Definition: localtime.c:111
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
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
int ParseDateTime ( char *  ,
char *  ,
char **  ,
int *  ,
int *  ,
char **   
)

Definition at line 1607 of file dt_common.c.

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

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

Referenced by PGTYPEStimestamp_defmt_asc().

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

Definition at line 731 of file dt_common.c.

Referenced by AppendSeconds(), and EncodeDateTime().

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

Variable Documentation

char* pgtypes_date_months[]
char* pgtypes_date_weekdays_short[]