PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
datetime.c File Reference
#include "postgres_fe.h"
#include <time.h>
#include <ctype.h>
#include <limits.h>
#include "dt.h"
#include "pgtypes_date.h"
#include "pgtypes_error.h"
#include "pgtypeslib_extern.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 327 of file datetime.c.

◆ PGTYPES_DATE_NUM_MAX_DIGITS

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

Definition at line 157 of file datetime.c.

◆ PGTYPES_FMTDATE_DAY_DIGITS_LZ

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

Definition at line 159 of file datetime.c.

◆ PGTYPES_FMTDATE_DOW_LITERAL_SHORT

#define PGTYPES_FMTDATE_DOW_LITERAL_SHORT   2

Definition at line 160 of file datetime.c.

◆ PGTYPES_FMTDATE_MONTH_DIGITS_LZ

#define PGTYPES_FMTDATE_MONTH_DIGITS_LZ   3

Definition at line 161 of file datetime.c.

◆ PGTYPES_FMTDATE_MONTH_LITERAL_SHORT

#define PGTYPES_FMTDATE_MONTH_LITERAL_SHORT   4

Definition at line 162 of file datetime.c.

◆ PGTYPES_FMTDATE_YEAR_DIGITS_LONG

#define PGTYPES_FMTDATE_YEAR_DIGITS_LONG   6

Definition at line 164 of file datetime.c.

◆ PGTYPES_FMTDATE_YEAR_DIGITS_SHORT

#define PGTYPES_FMTDATE_YEAR_DIGITS_SHORT   5

Definition at line 163 of file datetime.c.

Function Documentation

◆ PGTYPESdate_dayofweek()

int PGTYPESdate_dayofweek ( date  dDate)

Definition at line 138 of file datetime.c.

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 year, int month, int day)
Definition: datetime.c:296

References date2j().

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

◆ PGTYPESdate_defmt_asc()

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

Definition at line 329 of file datetime.c.

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

References date2j(), fmt, free, i, j, 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(), str, tm, pg_tm::tm_mday, pg_tm::tm_mon, pg_tm::tm_year, and token.

Referenced by main(), and rdefmtdate().

◆ PGTYPESdate_fmt_asc()

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

Definition at line 167 of file datetime.c.

169{
170 static struct
171 {
172 char *format;
173 int component;
174 } mapping[] =
175 {
176 /*
177 * format items have to be sorted according to their length, since the
178 * first pattern that matches gets replaced by its value
179 */
180 {
182 },
183 {
185 },
186 {
188 },
189 {
191 },
192 {
194 },
195 {
197 },
198 {
199 NULL, 0
200 }
201 };
202
203 union un_fmt_comb replace_val;
204 int replace_type;
205
206 int i;
207 int dow;
208 char *start_pattern;
209 struct tm tm;
210
211 /* copy the string over */
212 strcpy(outbuf, fmtstring);
213
214 /* get the date */
215 j2date(dDate + date2j(2000, 1, 1), &(tm.tm_year), &(tm.tm_mon), &(tm.tm_mday));
216 dow = PGTYPESdate_dayofweek(dDate);
217
218 for (i = 0; mapping[i].format != NULL; i++)
219 {
220 while ((start_pattern = strstr(outbuf, mapping[i].format)) != NULL)
221 {
222 switch (mapping[i].component)
223 {
225 replace_val.str_val = pgtypes_date_weekdays_short[dow];
226 replace_type = PGTYPES_TYPE_STRING_CONSTANT;
227 break;
229 replace_val.uint_val = tm.tm_mday;
230 replace_type = PGTYPES_TYPE_UINT_2_LZ;
231 break;
233 replace_val.str_val = months[tm.tm_mon - 1];
234 replace_type = PGTYPES_TYPE_STRING_CONSTANT;
235 break;
237 replace_val.uint_val = tm.tm_mon;
238 replace_type = PGTYPES_TYPE_UINT_2_LZ;
239 break;
241 replace_val.uint_val = tm.tm_year;
242 replace_type = PGTYPES_TYPE_UINT_4_LZ;
243 break;
245 replace_val.uint_val = tm.tm_year % 100;
246 replace_type = PGTYPES_TYPE_UINT_2_LZ;
247 break;
248 default:
249
250 /*
251 * should not happen, set something anyway
252 */
253 replace_val.str_val = " ";
254 replace_type = PGTYPES_TYPE_STRING_CONSTANT;
255 }
256 switch (replace_type)
257 {
260 memcpy(start_pattern, replace_val.str_val,
261 strlen(replace_val.str_val));
262 if (replace_type == PGTYPES_TYPE_STRING_MALLOCED)
263 free(replace_val.str_val);
264 break;
266 {
268
269 if (!t)
270 return -1;
272 "%u", replace_val.uint_val);
273 memcpy(start_pattern, t, strlen(t));
274 free(t);
275 }
276 break;
278 {
280
281 if (!t)
282 return -1;
284 "%02u", replace_val.uint_val);
285 memcpy(start_pattern, t, strlen(t));
286 free(t);
287 }
288 break;
290 {
292
293 if (!t)
294 return -1;
296 "%04u", replace_val.uint_val);
297 memcpy(start_pattern, t, strlen(t));
298 free(t);
299 }
300 break;
301 default:
302
303 /*
304 * doesn't happen (we set replace_type to
305 * PGTYPES_TYPE_STRING_CONSTANT in case of an error above)
306 */
307 break;
308 }
309 }
310 }
311 return 0;
void j2date(int jd, int *year, int *month, int *day)
Definition: datetime.c:321
char * pgtypes_date_weekdays_short[]
Definition: dt_common.c:497
int PGTYPESdate_dayofweek(date dDate)
Definition: datetime.c:138
#define PGTYPES_FMTDATE_DAY_DIGITS_LZ
Definition: datetime.c:159
#define PGTYPES_FMTDATE_MONTH_DIGITS_LZ
Definition: datetime.c:161
#define PGTYPES_FMTDATE_DOW_LITERAL_SHORT
Definition: datetime.c:160
#define PGTYPES_FMTDATE_YEAR_DIGITS_LONG
Definition: datetime.c:164
#define PGTYPES_FMTDATE_YEAR_DIGITS_SHORT
Definition: datetime.c:163
#define PGTYPES_DATE_NUM_MAX_DIGITS
Definition: datetime.c:157
#define PGTYPES_FMTDATE_MONTH_LITERAL_SHORT
Definition: datetime.c:162
static char format
#define PGTYPES_TYPE_STRING_CONSTANT
#define PGTYPES_TYPE_UINT
#define PGTYPES_TYPE_STRING_MALLOCED
#define PGTYPES_TYPE_UINT_4_LZ
#define PGTYPES_TYPE_UINT_2_LZ
#define snprintf
Definition: port.h:238

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, pg_tm::tm_mday, pg_tm::tm_mon, pg_tm::tm_year, and un_fmt_comb::uint_val.

Referenced by main(), and rfmtdate().

◆ PGTYPESdate_free()

void PGTYPESdate_free ( date d)

Definition at line 25 of file datetime.c.

26{
27 free(d);
28}

References free.

Referenced by main().

◆ PGTYPESdate_from_asc()

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

Definition at line 47 of file datetime.c.

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 {
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 {
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 {
86 return INT_MIN;
87 }
88 break;
89
90 default:
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}
int ParseDateTime(const char *timestr, char *workbuf, size_t buflen, char **field, int *ftype, int maxfields, int *numfields)
Definition: datetime.c:764
int DecodeDateTime(char **field, int *ftype, int nf, int *dtype, struct pg_tm *tm, fsec_t *fsec, int *tzp, DateTimeErrorExtra *extra)
Definition: datetime.c:988
void GetEpochTime(struct pg_tm *tm)
Definition: timestamp.c:2149
int32 fsec_t
Definition: timestamp.h:41
#define MAXDATEFIELDS
Definition: datetime.h:202
#define DTK_EPOCH
Definition: datetime.h:152
#define DTK_DATE
Definition: datetime.h:144
#define MAXDATELEN
Definition: datetime.h:200
long date
Definition: pgtypes_date.h:9
#define PGTYPES_DATE_BAD_DATE
Definition: pgtypes_error.h:8

References date2j(), DecodeDateTime(), DTK_DATE, DTK_EPOCH, GetEpochTime(), MAXDATEFIELDS, MAXDATELEN, ParseDateTime(), PGTYPES_DATE_BAD_DATE, str, tm, pg_tm::tm_mday, pg_tm::tm_mon, and pg_tm::tm_year.

Referenced by ecpg_get_data(), and main().

◆ PGTYPESdate_from_timestamp()

date PGTYPESdate_from_timestamp ( timestamp  dt)

Definition at line 31 of file datetime.c.

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}
#define USECS_PER_DAY
Definition: timestamp.h:131
#define TIMESTAMP_NOT_FINITE(j)
Definition: timestamp.h:169

References TIMESTAMP_NOT_FINITE, and USECS_PER_DAY.

Referenced by main(), and PGTYPEStimestamp_fmt_asc().

◆ PGTYPESdate_julmdy()

void PGTYPESdate_julmdy ( date  jd,
int *  mdy 
)

Definition at line 115 of file datetime.c.

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}
int y
Definition: isn.c:71

References date2j(), j2date(), and y.

Referenced by main(), and rjulmdy().

◆ PGTYPESdate_mdyjul()

void PGTYPESdate_mdyjul ( int *  mdy,
date jdate 
)

Definition at line 128 of file datetime.c.

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}

References date2j().

Referenced by main(), and rmdyjul().

◆ PGTYPESdate_new()

date * PGTYPESdate_new ( void  )

Definition at line 15 of file datetime.c.

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}

References pgtypes_alloc().

Referenced by main().

◆ PGTYPESdate_to_asc()

char * PGTYPESdate_to_asc ( date  dDate)

Definition at line 101 of file datetime.c.

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}
void EncodeDateOnly(struct pg_tm *tm, int style, char *str)
Definition: datetime.c:4343
int DateStyle
Definition: globals.c:124
static char * buf
Definition: pg_test_fsync.c:72

References buf, date2j(), DateStyle, EncodeDateOnly(), j2date(), MAXDATELEN, pgtypes_strdup(), tm, pg_tm::tm_mday, pg_tm::tm_mon, and pg_tm::tm_year.

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

◆ PGTYPESdate_today()

void PGTYPESdate_today ( date d)

Definition at line 148 of file datetime.c.

149{
150 struct tm ts;
151
153 if (errno == 0)
154 *d = date2j(ts.tm_year, ts.tm_mon, ts.tm_mday) - date2j(2000, 1, 1);
155}
void GetCurrentDateTime(struct pg_tm *tm)
Definition: datetime.c:376

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

Referenced by rtoday().