PostgreSQL Source Code  git master
datetime.c File Reference
#include "postgres_fe.h"
#include <time.h>
#include <ctype.h>
#include <limits.h>
#include "pgtypeslib_extern.h"
#include "dt.h"
#include "pgtypes_error.h"
#include "pgtypes_date.h"
Include dependency graph for datetime.c:

Go to the source code of this file.

Macros

#define PGTYPES_DATE_NUM_MAX_DIGITS
 
#define PGTYPES_FMTDATE_DAY_DIGITS_LZ   1 /* LZ means "leading zeroes" */
 
#define PGTYPES_FMTDATE_DOW_LITERAL_SHORT   2
 
#define PGTYPES_FMTDATE_MONTH_DIGITS_LZ   3
 
#define PGTYPES_FMTDATE_MONTH_LITERAL_SHORT   4
 
#define PGTYPES_FMTDATE_YEAR_DIGITS_SHORT   5
 
#define PGTYPES_FMTDATE_YEAR_DIGITS_LONG   6
 
#define PGTYPES_DATE_MONTH_MAXLENGTH   20 /* probably even less :-) */
 

Functions

datePGTYPESdate_new (void)
 
void PGTYPESdate_free (date *d)
 
date PGTYPESdate_from_timestamp (timestamp dt)
 
date PGTYPESdate_from_asc (char *str, char **endptr)
 
char * PGTYPESdate_to_asc (date dDate)
 
void PGTYPESdate_julmdy (date jd, int *mdy)
 
void PGTYPESdate_mdyjul (int *mdy, date *jdate)
 
int PGTYPESdate_dayofweek (date dDate)
 
void PGTYPESdate_today (date *d)
 
int PGTYPESdate_fmt_asc (date dDate, const char *fmtstring, char *outbuf)
 
int PGTYPESdate_defmt_asc (date *d, const char *fmt, const char *str)
 

Macro Definition Documentation

◆ PGTYPES_DATE_MONTH_MAXLENGTH

#define PGTYPES_DATE_MONTH_MAXLENGTH   20 /* probably even less :-) */

Definition at line 329 of file datetime.c.

Referenced by PGTYPESdate_defmt_asc().

◆ PGTYPES_DATE_NUM_MAX_DIGITS

#define PGTYPES_DATE_NUM_MAX_DIGITS
Value:
20 /* should suffice for most
* years... */

Definition at line 158 of file datetime.c.

Referenced by PGTYPESdate_fmt_asc().

◆ PGTYPES_FMTDATE_DAY_DIGITS_LZ

#define PGTYPES_FMTDATE_DAY_DIGITS_LZ   1 /* LZ means "leading zeroes" */

Definition at line 161 of file datetime.c.

Referenced by PGTYPESdate_fmt_asc().

◆ PGTYPES_FMTDATE_DOW_LITERAL_SHORT

#define PGTYPES_FMTDATE_DOW_LITERAL_SHORT   2

Definition at line 162 of file datetime.c.

Referenced by PGTYPESdate_fmt_asc().

◆ PGTYPES_FMTDATE_MONTH_DIGITS_LZ

#define PGTYPES_FMTDATE_MONTH_DIGITS_LZ   3

Definition at line 163 of file datetime.c.

Referenced by PGTYPESdate_fmt_asc().

◆ PGTYPES_FMTDATE_MONTH_LITERAL_SHORT

#define PGTYPES_FMTDATE_MONTH_LITERAL_SHORT   4

Definition at line 164 of file datetime.c.

Referenced by PGTYPESdate_fmt_asc().

◆ PGTYPES_FMTDATE_YEAR_DIGITS_LONG

#define PGTYPES_FMTDATE_YEAR_DIGITS_LONG   6

Definition at line 166 of file datetime.c.

Referenced by PGTYPESdate_fmt_asc().

◆ PGTYPES_FMTDATE_YEAR_DIGITS_SHORT

#define PGTYPES_FMTDATE_YEAR_DIGITS_SHORT   5

Definition at line 165 of file datetime.c.

Referenced by PGTYPESdate_fmt_asc().

Function Documentation

◆ PGTYPESdate_dayofweek()

int PGTYPESdate_dayofweek ( date  dDate)

Definition at line 138 of file datetime.c.

References date2j().

Referenced by main(), PGTYPESdate_fmt_asc(), PGTYPEStimestamp_fmt_asc(), and rdayofweek().

139 {
140  /*
141  * Sunday: 0 Monday: 1 Tuesday: 2 Wednesday: 3 Thursday: 4
142  * Friday: 5 Saturday: 6
143  */
144  return (int) (dDate + date2j(2000, 1, 1) + 1) % 7;
145 }
int date2j(int y, int m, int d)
Definition: datetime.c:270

◆ PGTYPESdate_defmt_asc()

int PGTYPESdate_defmt_asc ( date d,
const char *  fmt,
const char *  str 
)

Definition at line 331 of file datetime.c.

References date2j(), free, i, sort-test::list, months, MONTHS_PER_YEAR, pg_tolower(), pgtypes_alloc(), PGTYPES_DATE_BAD_DAY, PGTYPES_DATE_BAD_MONTH, PGTYPES_DATE_ERR_EARGS, PGTYPES_DATE_ERR_ENOSHORTDATE, PGTYPES_DATE_ERR_ENOTDMY, PGTYPES_DATE_MONTH_MAXLENGTH, pgtypes_date_months, pgtypes_strdup(), tm, and pg_tm::tm_year.

Referenced by main(), and rdefmtdate().

332 {
333  /*
334  * token[2] = { 4,6 } means that token 2 starts at position 4 and ends at
335  * (including) position 6
336  */
337  int token[3][2];
338  int token_values[3] = {-1, -1, -1};
339  char *fmt_token_order;
340  char *fmt_ystart,
341  *fmt_mstart,
342  *fmt_dstart;
343  unsigned int i;
344  int reading_digit;
345  int token_count;
346  char *str_copy;
347  struct tm tm;
348 
349  tm.tm_year = tm.tm_mon = tm.tm_mday = 0; /* keep compiler quiet */
350 
351  if (!d || !str || !fmt)
352  {
353  errno = PGTYPES_DATE_ERR_EARGS;
354  return -1;
355  }
356 
357  /* analyze the fmt string */
358  fmt_ystart = strstr(fmt, "yy");
359  fmt_mstart = strstr(fmt, "mm");
360  fmt_dstart = strstr(fmt, "dd");
361 
362  if (!fmt_ystart || !fmt_mstart || !fmt_dstart)
363  {
364  errno = PGTYPES_DATE_ERR_EARGS;
365  return -1;
366  }
367 
368  if (fmt_ystart < fmt_mstart)
369  {
370  /* y m */
371  if (fmt_dstart < fmt_ystart)
372  {
373  /* d y m */
374  fmt_token_order = "dym";
375  }
376  else if (fmt_dstart > fmt_mstart)
377  {
378  /* y m d */
379  fmt_token_order = "ymd";
380  }
381  else
382  {
383  /* y d m */
384  fmt_token_order = "ydm";
385  }
386  }
387  else
388  {
389  /* fmt_ystart > fmt_mstart */
390  /* m y */
391  if (fmt_dstart < fmt_mstart)
392  {
393  /* d m y */
394  fmt_token_order = "dmy";
395  }
396  else if (fmt_dstart > fmt_ystart)
397  {
398  /* m y d */
399  fmt_token_order = "myd";
400  }
401  else
402  {
403  /* m d y */
404  fmt_token_order = "mdy";
405  }
406  }
407 
408  /*
409  * handle the special cases where there is no delimiter between the
410  * digits. If we see this:
411  *
412  * only digits, 6 or 8 bytes then it might be ddmmyy and ddmmyyyy (or
413  * similar)
414  *
415  * we reduce it to a string with delimiters and continue processing
416  */
417 
418  /* check if we have only digits */
419  reading_digit = 1;
420  for (i = 0; str[i]; i++)
421  {
422  if (!isdigit((unsigned char) str[i]))
423  {
424  reading_digit = 0;
425  break;
426  }
427  }
428  if (reading_digit)
429  {
430  int frag_length[3];
431  int target_pos;
432 
433  i = strlen(str);
434  if (i != 8 && i != 6)
435  {
437  return -1;
438  }
439  /* okay, this really is the special case */
440 
441  /*
442  * as long as the string, one additional byte for the terminator and 2
443  * for the delimiters between the 3 fields
444  */
445  str_copy = pgtypes_alloc(strlen(str) + 1 + 2);
446  if (!str_copy)
447  return -1;
448 
449  /* determine length of the fragments */
450  if (i == 6)
451  {
452  frag_length[0] = 2;
453  frag_length[1] = 2;
454  frag_length[2] = 2;
455  }
456  else
457  {
458  if (fmt_token_order[0] == 'y')
459  {
460  frag_length[0] = 4;
461  frag_length[1] = 2;
462  frag_length[2] = 2;
463  }
464  else if (fmt_token_order[1] == 'y')
465  {
466  frag_length[0] = 2;
467  frag_length[1] = 4;
468  frag_length[2] = 2;
469  }
470  else
471  {
472  frag_length[0] = 2;
473  frag_length[1] = 2;
474  frag_length[2] = 4;
475  }
476  }
477  target_pos = 0;
478 
479  /*
480  * XXX: Here we could calculate the positions of the tokens and save
481  * the for loop down there where we again check with isdigit() for
482  * digits.
483  */
484  for (i = 0; i < 3; i++)
485  {
486  int start_pos = 0;
487 
488  if (i >= 1)
489  start_pos += frag_length[0];
490  if (i == 2)
491  start_pos += frag_length[1];
492 
493  strncpy(str_copy + target_pos, str + start_pos,
494  frag_length[i]);
495  target_pos += frag_length[i];
496  if (i != 2)
497  {
498  str_copy[target_pos] = ' ';
499  target_pos++;
500  }
501  }
502  str_copy[target_pos] = '\0';
503  }
504  else
505  {
506  str_copy = pgtypes_strdup(str);
507  if (!str_copy)
508  return -1;
509 
510  /* convert the whole string to lower case */
511  for (i = 0; str_copy[i]; i++)
512  str_copy[i] = (char) pg_tolower((unsigned char) str_copy[i]);
513  }
514 
515  /* look for numerical tokens */
516  reading_digit = 0;
517  token_count = 0;
518  for (i = 0; i < strlen(str_copy); i++)
519  {
520  if (!isdigit((unsigned char) str_copy[i]) && reading_digit)
521  {
522  /* the token is finished */
523  token[token_count][1] = i - 1;
524  reading_digit = 0;
525  token_count++;
526  }
527  else if (isdigit((unsigned char) str_copy[i]) && !reading_digit)
528  {
529  /* we have found a token */
530  token[token_count][0] = i;
531  reading_digit = 1;
532  }
533  }
534 
535  /*
536  * we're at the end of the input string, but maybe we are still reading a
537  * number...
538  */
539  if (reading_digit)
540  {
541  token[token_count][1] = i - 1;
542  token_count++;
543  }
544 
545 
546  if (token_count < 2)
547  {
548  /*
549  * not all tokens found, no way to find 2 missing tokens with string
550  * matches
551  */
552  free(str_copy);
554  return -1;
555  }
556 
557  if (token_count != 3)
558  {
559  /*
560  * not all tokens found but we may find another one with string
561  * matches by testing for the months names and months abbreviations
562  */
563  char *month_lower_tmp = pgtypes_alloc(PGTYPES_DATE_MONTH_MAXLENGTH);
564  char *start_pos;
565  int j;
566  int offset;
567  int found = 0;
568  char **list;
569 
570  if (!month_lower_tmp)
571  {
572  /* free variables we alloc'ed before */
573  free(str_copy);
574  return -1;
575  }
576  list = pgtypes_date_months;
577  for (i = 0; list[i]; i++)
578  {
579  for (j = 0; j < PGTYPES_DATE_MONTH_MAXLENGTH; j++)
580  {
581  month_lower_tmp[j] = (char) pg_tolower((unsigned char) list[i][j]);
582  if (!month_lower_tmp[j])
583  {
584  /* properly terminated */
585  break;
586  }
587  }
588  if ((start_pos = strstr(str_copy, month_lower_tmp)))
589  {
590  offset = start_pos - str_copy;
591 
592  /*
593  * sort the new token into the numeric tokens, shift them if
594  * necessary
595  */
596  if (offset < token[0][0])
597  {
598  token[2][0] = token[1][0];
599  token[2][1] = token[1][1];
600  token[1][0] = token[0][0];
601  token[1][1] = token[0][1];
602  token_count = 0;
603  }
604  else if (offset < token[1][0])
605  {
606  token[2][0] = token[1][0];
607  token[2][1] = token[1][1];
608  token_count = 1;
609  }
610  else
611  token_count = 2;
612  token[token_count][0] = offset;
613  token[token_count][1] = offset + strlen(month_lower_tmp) - 1;
614 
615  /*
616  * the value is the index of the month in the array of months
617  * + 1 (January is month 0)
618  */
619  token_values[token_count] = i + 1;
620  found = 1;
621  break;
622  }
623 
624  /*
625  * evil[tm] hack: if we read the pgtypes_date_months and haven't
626  * found a match, reset list to point to months (abbreviations)
627  * and reset the counter variable i
628  */
629  if (list == pgtypes_date_months)
630  {
631  if (list[i + 1] == NULL)
632  {
633  list = months;
634  i = -1;
635  }
636  }
637  }
638  if (!found)
639  {
640  free(month_lower_tmp);
641  free(str_copy);
642  errno = PGTYPES_DATE_ERR_ENOTDMY;
643  return -1;
644  }
645 
646  /*
647  * here we found a month. token[token_count] and
648  * token_values[token_count] reflect the month's details.
649  *
650  * only the month can be specified with a literal. Here we can do a
651  * quick check if the month is at the right position according to the
652  * format string because we can check if the token that we expect to
653  * be the month is at the position of the only token that already has
654  * a value. If we wouldn't check here we could say "December 4 1990"
655  * with a fmt string of "dd mm yy" for 12 April 1990.
656  */
657  if (fmt_token_order[token_count] != 'm')
658  {
659  /* deal with the error later on */
660  token_values[token_count] = -1;
661  }
662  free(month_lower_tmp);
663  }
664 
665  /* terminate the tokens with ASCII-0 and get their values */
666  for (i = 0; i < 3; i++)
667  {
668  *(str_copy + token[i][1] + 1) = '\0';
669  /* A month already has a value set, check for token_value == -1 */
670  if (token_values[i] == -1)
671  {
672  errno = 0;
673  token_values[i] = strtol(str_copy + token[i][0], (char **) NULL, 10);
674  /* strtol sets errno in case of an error */
675  if (errno)
676  token_values[i] = -1;
677  }
678  if (fmt_token_order[i] == 'd')
679  tm.tm_mday = token_values[i];
680  else if (fmt_token_order[i] == 'm')
681  tm.tm_mon = token_values[i];
682  else if (fmt_token_order[i] == 'y')
683  tm.tm_year = token_values[i];
684  }
685  free(str_copy);
686 
687  if (tm.tm_mday < 1 || tm.tm_mday > 31)
688  {
689  errno = PGTYPES_DATE_BAD_DAY;
690  return -1;
691  }
692 
693  if (tm.tm_mon < 1 || tm.tm_mon > MONTHS_PER_YEAR)
694  {
695  errno = PGTYPES_DATE_BAD_MONTH;
696  return -1;
697  }
698 
699  if (tm.tm_mday == 31 && (tm.tm_mon == 4 || tm.tm_mon == 6 || tm.tm_mon == 9 || tm.tm_mon == 11))
700  {
701  errno = PGTYPES_DATE_BAD_DAY;
702  return -1;
703  }
704 
705  if (tm.tm_mon == 2 && tm.tm_mday > 29)
706  {
707  errno = PGTYPES_DATE_BAD_DAY;
708  return -1;
709  }
710 
711  *d = date2j(tm.tm_year, tm.tm_mon, tm.tm_mday) - date2j(2000, 1, 1);
712 
713  return 0;
714 }
#define PGTYPES_DATE_BAD_DAY
Definition: pgtypes_error.h:12
#define PGTYPES_DATE_ERR_EARGS
Definition: pgtypes_error.h:9
#define PGTYPES_DATE_ERR_ENOTDMY
Definition: pgtypes_error.h:11
unsigned char pg_tolower(unsigned char ch)
Definition: pgstrcasecmp.c:122
#define PGTYPES_DATE_BAD_MONTH
Definition: pgtypes_error.h:13
static struct pg_tm tm
Definition: localtime.c:108
#define MONTHS_PER_YEAR
Definition: timestamp.h:69
char * pgtypes_strdup(const char *str)
Definition: common.c:20
const char *const months[]
Definition: datetime.c:66
#define PGTYPES_DATE_ERR_ENOSHORTDATE
Definition: pgtypes_error.h:10
char * pgtypes_alloc(long size)
Definition: common.c:10
int tm_mday
Definition: pgtime.h:30
int tm_mon
Definition: pgtime.h:31
#define PGTYPES_DATE_MONTH_MAXLENGTH
Definition: datetime.c:329
int date2j(int y, int m, int d)
Definition: datetime.c:270
char * pgtypes_date_months[]
Definition: dt_common.c:499
#define free(a)
Definition: header.h:65
int tm_year
Definition: pgtime.h:32
int i

◆ PGTYPESdate_fmt_asc()

int PGTYPESdate_fmt_asc ( date  dDate,
const char *  fmtstring,
char *  outbuf 
)

Definition at line 169 of file datetime.c.

References date2j(), format, free, i, j2date(), months, pgtypes_alloc(), PGTYPES_DATE_NUM_MAX_DIGITS, pgtypes_date_weekdays_short, PGTYPES_FMTDATE_DAY_DIGITS_LZ, PGTYPES_FMTDATE_DOW_LITERAL_SHORT, PGTYPES_FMTDATE_MONTH_DIGITS_LZ, PGTYPES_FMTDATE_MONTH_LITERAL_SHORT, PGTYPES_FMTDATE_YEAR_DIGITS_LONG, PGTYPES_FMTDATE_YEAR_DIGITS_SHORT, PGTYPES_TYPE_STRING_CONSTANT, PGTYPES_TYPE_STRING_MALLOCED, PGTYPES_TYPE_UINT, PGTYPES_TYPE_UINT_2_LZ, PGTYPES_TYPE_UINT_4_LZ, PGTYPESdate_dayofweek(), snprintf, un_fmt_comb::str_val, tm, and un_fmt_comb::uint_val.

Referenced by main(), and rfmtdate().

170 {
171  static struct
172  {
173  char *format;
174  int component;
175  } mapping[] =
176  {
177  /*
178  * format items have to be sorted according to their length, since the
179  * first pattern that matches gets replaced by its value
180  */
181  {
183  },
184  {
186  },
187  {
189  },
190  {
192  },
193  {
195  },
196  {
198  },
199  {
200  NULL, 0
201  }
202  };
203 
204  union un_fmt_comb replace_val;
205  int replace_type;
206 
207  int i;
208  int dow;
209  char *start_pattern;
210  struct tm tm;
211 
212  /* copy the string over */
213  strcpy(outbuf, fmtstring);
214 
215  /* get the date */
216  j2date(dDate + date2j(2000, 1, 1), &(tm.tm_year), &(tm.tm_mon), &(tm.tm_mday));
217  dow = PGTYPESdate_dayofweek(dDate);
218 
219  for (i = 0; mapping[i].format != NULL; i++)
220  {
221  while ((start_pattern = strstr(outbuf, mapping[i].format)) != NULL)
222  {
223  switch (mapping[i].component)
224  {
226  replace_val.str_val = pgtypes_date_weekdays_short[dow];
227  replace_type = PGTYPES_TYPE_STRING_CONSTANT;
228  break;
230  replace_val.uint_val = tm.tm_mday;
231  replace_type = PGTYPES_TYPE_UINT_2_LZ;
232  break;
234  replace_val.str_val = months[tm.tm_mon - 1];
235  replace_type = PGTYPES_TYPE_STRING_CONSTANT;
236  break;
238  replace_val.uint_val = tm.tm_mon;
239  replace_type = PGTYPES_TYPE_UINT_2_LZ;
240  break;
242  replace_val.uint_val = tm.tm_year;
243  replace_type = PGTYPES_TYPE_UINT_4_LZ;
244  break;
246  replace_val.uint_val = tm.tm_year % 100;
247  replace_type = PGTYPES_TYPE_UINT_2_LZ;
248  break;
249  default:
250 
251  /*
252  * should not happen, set something anyway
253  */
254  replace_val.str_val = " ";
255  replace_type = PGTYPES_TYPE_STRING_CONSTANT;
256  }
257  switch (replace_type)
258  {
261  memcpy(start_pattern, replace_val.str_val,
262  strlen(replace_val.str_val));
263  if (replace_type == PGTYPES_TYPE_STRING_MALLOCED)
264  free(replace_val.str_val);
265  break;
266  case PGTYPES_TYPE_UINT:
267  {
269 
270  if (!t)
271  return -1;
273  "%u", replace_val.uint_val);
274  memcpy(start_pattern, t, strlen(t));
275  free(t);
276  }
277  break;
279  {
281 
282  if (!t)
283  return -1;
285  "%02u", replace_val.uint_val);
286  memcpy(start_pattern, t, strlen(t));
287  free(t);
288  }
289  break;
291  {
293 
294  if (!t)
295  return -1;
297  "%04u", replace_val.uint_val);
298  memcpy(start_pattern, t, strlen(t));
299  free(t);
300  }
301  break;
302  default:
303 
304  /*
305  * doesn't happen (we set replace_type to
306  * PGTYPES_TYPE_STRING_CONSTANT in case of an error above)
307  */
308  break;
309  }
310  }
311  }
312  return 0;
313 }
#define PGTYPES_TYPE_UINT_4_LZ
#define PGTYPES_FMTDATE_DAY_DIGITS_LZ
Definition: datetime.c:161
char * pgtypes_date_weekdays_short[]
Definition: dt_common.c:497
#define PGTYPES_TYPE_UINT_2_LZ
#define PGTYPES_TYPE_STRING_CONSTANT
#define PGTYPES_DATE_NUM_MAX_DIGITS
Definition: datetime.c:158
static struct pg_tm tm
Definition: localtime.c:108
const char *const months[]
Definition: datetime.c:66
#define PGTYPES_TYPE_UINT
char * pgtypes_alloc(long size)
Definition: common.c:10
int tm_mday
Definition: pgtime.h:30
int tm_mon
Definition: pgtime.h:31
#define PGTYPES_FMTDATE_YEAR_DIGITS_LONG
Definition: datetime.c:166
void j2date(int jd, int *year, int *month, int *day)
Definition: datetime.c:295
#define PGTYPES_TYPE_STRING_MALLOCED
#define PGTYPES_FMTDATE_YEAR_DIGITS_SHORT
Definition: datetime.c:165
int date2j(int y, int m, int d)
Definition: datetime.c:270
#define free(a)
Definition: header.h:65
#define PGTYPES_FMTDATE_MONTH_LITERAL_SHORT
Definition: datetime.c:164
int tm_year
Definition: pgtime.h:32
int i
int PGTYPESdate_dayofweek(date dDate)
Definition: datetime.c:138
#define PGTYPES_FMTDATE_DOW_LITERAL_SHORT
Definition: datetime.c:162
static char format
Definition: pg_basebackup.c:85
#define snprintf
Definition: port.h:192
#define PGTYPES_FMTDATE_MONTH_DIGITS_LZ
Definition: datetime.c:163

◆ PGTYPESdate_free()

void PGTYPESdate_free ( date d)

Definition at line 25 of file datetime.c.

References free.

Referenced by main().

26 {
27  free(d);
28 }
#define free(a)
Definition: header.h:65

◆ PGTYPESdate_from_asc()

date PGTYPESdate_from_asc ( char *  str,
char **  endptr 
)

Definition at line 47 of file datetime.c.

References date2j(), DecodeDateTime(), DTK_DATE, DTK_EPOCH, GetEpochTime(), MAXDATEFIELDS, MAXDATELEN, ParseDateTime(), PGTYPES_DATE_BAD_DATE, and tm.

Referenced by ecpg_get_data(), and main().

48 {
49  date dDate;
50  fsec_t fsec;
51  struct tm tt,
52  *tm = &tt;
53  int dtype;
54  int nf;
55  char *field[MAXDATEFIELDS];
56  int ftype[MAXDATEFIELDS];
57  char lowstr[MAXDATELEN + MAXDATEFIELDS];
58  char *realptr;
59  char **ptr = (endptr != NULL) ? endptr : &realptr;
60 
61  bool EuroDates = false;
62 
63  errno = 0;
64  if (strlen(str) > MAXDATELEN)
65  {
66  errno = PGTYPES_DATE_BAD_DATE;
67  return INT_MIN;
68  }
69 
70  if (ParseDateTime(str, lowstr, field, ftype, &nf, ptr) != 0 ||
71  DecodeDateTime(field, ftype, nf, &dtype, tm, &fsec, EuroDates) != 0)
72  {
73  errno = PGTYPES_DATE_BAD_DATE;
74  return INT_MIN;
75  }
76 
77  switch (dtype)
78  {
79  case DTK_DATE:
80  break;
81 
82  case DTK_EPOCH:
83  if (GetEpochTime(tm) < 0)
84  {
85  errno = PGTYPES_DATE_BAD_DATE;
86  return INT_MIN;
87  }
88  break;
89 
90  default:
91  errno = PGTYPES_DATE_BAD_DATE;
92  return INT_MIN;
93  }
94 
95  dDate = (date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - date2j(2000, 1, 1));
96 
97  return dDate;
98 }
#define MAXDATELEN
Definition: datetime.h:201
#define PGTYPES_DATE_BAD_DATE
Definition: pgtypes_error.h:8
long date
Definition: pgtypes_date.h:9
static struct pg_tm tm
Definition: localtime.c:108
int DecodeDateTime(char **field, int *ftype, int nf, int *dtype, struct pg_tm *tm, fsec_t *fsec, int *tzp)
Definition: datetime.c:761
int32 fsec_t
Definition: timestamp.h:41
int date2j(int y, int m, int d)
Definition: datetime.c:270
#define MAXDATEFIELDS
Definition: datetime.h:203
#define DTK_EPOCH
Definition: datetime.h:153
void GetEpochTime(struct pg_tm *tm)
Definition: timestamp.c:2017
int ParseDateTime(const char *timestr, char *workbuf, size_t buflen, char **field, int *ftype, int maxfields, int *numfields)
Definition: datetime.c:540
#define DTK_DATE
Definition: datetime.h:145

◆ PGTYPESdate_from_timestamp()

date PGTYPESdate_from_timestamp ( timestamp  dt)

Definition at line 31 of file datetime.c.

References TIMESTAMP_NOT_FINITE, and USECS_PER_DAY.

Referenced by main(), and PGTYPEStimestamp_fmt_asc().

32 {
33  date dDate;
34 
35  dDate = 0; /* suppress compiler warning */
36 
37  if (!TIMESTAMP_NOT_FINITE(dt))
38  {
39  /* Microseconds to days */
40  dDate = (dt / USECS_PER_DAY);
41  }
42 
43  return dDate;
44 }
long date
Definition: pgtypes_date.h:9
#define TIMESTAMP_NOT_FINITE(j)
Definition: timestamp.h:122
#define USECS_PER_DAY
Definition: timestamp.h:91

◆ PGTYPESdate_julmdy()

void PGTYPESdate_julmdy ( date  jd,
int *  mdy 
)

Definition at line 115 of file datetime.c.

References date2j(), and j2date().

Referenced by main(), and rjulmdy().

116 {
117  int y,
118  m,
119  d;
120 
121  j2date((int) (jd + date2j(2000, 1, 1)), &y, &m, &d);
122  mdy[0] = m;
123  mdy[1] = d;
124  mdy[2] = y;
125 }
void j2date(int jd, int *year, int *month, int *day)
Definition: datetime.c:295
int date2j(int y, int m, int d)
Definition: datetime.c:270

◆ PGTYPESdate_mdyjul()

void PGTYPESdate_mdyjul ( int *  mdy,
date jdate 
)

Definition at line 128 of file datetime.c.

References date2j().

Referenced by main(), and rmdyjul().

129 {
130  /* month is mdy[0] */
131  /* day is mdy[1] */
132  /* year is mdy[2] */
133 
134  *jdate = (date) (date2j(mdy[2], mdy[0], mdy[1]) - date2j(2000, 1, 1));
135 }
long date
Definition: pgtypes_date.h:9
int date2j(int y, int m, int d)
Definition: datetime.c:270

◆ PGTYPESdate_new()

date* PGTYPESdate_new ( void  )

Definition at line 15 of file datetime.c.

References pgtypes_alloc().

Referenced by main().

16 {
17  date *result;
18 
19  result = (date *) pgtypes_alloc(sizeof(date));
20  /* result can be NULL if we run out of memory */
21  return result;
22 }
long date
Definition: pgtypes_date.h:9
char * pgtypes_alloc(long size)
Definition: common.c:10

◆ PGTYPESdate_to_asc()

char* PGTYPESdate_to_asc ( date  dDate)

Definition at line 101 of file datetime.c.

References buf, date2j(), DateStyle, EncodeDateOnly(), j2date(), MAXDATELEN, pgtypes_strdup(), and tm.

Referenced by ecpg_store_input(), main(), and rdatestr().

102 {
103  struct tm tt,
104  *tm = &tt;
105  char buf[MAXDATELEN + 1];
106  int DateStyle = 1;
107  bool EuroDates = false;
108 
109  j2date(dDate + date2j(2000, 1, 1), &(tm->tm_year), &(tm->tm_mon), &(tm->tm_mday));
110  EncodeDateOnly(tm, DateStyle, buf, EuroDates);
111  return pgtypes_strdup(buf);
112 }
#define MAXDATELEN
Definition: datetime.h:201
void EncodeDateOnly(struct pg_tm *tm, int style, char *str)
Definition: datetime.c:3858
static struct pg_tm tm
Definition: localtime.c:108
char * pgtypes_strdup(const char *str)
Definition: common.c:20
static char * buf
Definition: pg_test_fsync.c:68
void j2date(int jd, int *year, int *month, int *day)
Definition: datetime.c:295
int date2j(int y, int m, int d)
Definition: datetime.c:270
int DateStyle
Definition: globals.c:115

◆ PGTYPESdate_today()

void PGTYPESdate_today ( date d)

Definition at line 148 of file datetime.c.

References date2j(), GetCurrentDateTime(), and tm.

Referenced by rtoday().

149 {
150  struct tm ts;
151 
152  GetCurrentDateTime(&ts);
153  if (errno == 0)
154  *d = date2j(ts.tm_year, ts.tm_mon, ts.tm_mday) - date2j(2000, 1, 1);
155  return;
156 }
void GetCurrentDateTime(struct pg_tm *tm)
Definition: datetime.c:348
static struct pg_tm tm
Definition: localtime.c:108
int date2j(int y, int m, int d)
Definition: datetime.c:270