PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
timestamp.c File Reference
#include "postgres_fe.h"
#include <time.h>
#include <float.h>
#include <limits.h>
#include <math.h>
#include "extern.h"
#include "dt.h"
#include "pgtypes_timestamp.h"
#include "pgtypes_date.h"
Include dependency graph for timestamp.c:

Go to the source code of this file.

Functions

static int64 time2t (const int hour, const int min, const int sec, const fsec_t fsec)
 
static timestamp dt2local (timestamp dt, int tz)
 
int tm2timestamp (struct tm *tm, fsec_t fsec, int *tzp, timestamp *result)
 
static timestamp SetEpochTimestamp (void)
 
static int timestamp2tm (timestamp dt, int *tzp, struct tm *tm, fsec_t *fsec, const char **tzn)
 
static int EncodeSpecialTimestamp (timestamp dt, char *str)
 
timestamp PGTYPEStimestamp_from_asc (char *str, char **endptr)
 
char * PGTYPEStimestamp_to_asc (timestamp tstamp)
 
void PGTYPEStimestamp_current (timestamp *ts)
 
static int dttofmtasc_replace (timestamp *ts, date dDate, int dow, struct tm *tm, char *output, int *pstr_len, const char *fmtstr)
 
int PGTYPEStimestamp_fmt_asc (timestamp *ts, char *output, int str_len, const char *fmtstr)
 
int PGTYPEStimestamp_sub (timestamp *ts1, timestamp *ts2, interval *iv)
 
int PGTYPEStimestamp_defmt_asc (char *str, const char *fmt, timestamp *d)
 
int PGTYPEStimestamp_add_interval (timestamp *tin, interval *span, timestamp *tout)
 
int PGTYPEStimestamp_sub_interval (timestamp *tin, interval *span, timestamp *tout)
 

Function Documentation

static timestamp dt2local ( timestamp  dt,
int  tz 
)
static

Definition at line 28 of file timestamp.c.

References USECS_PER_SEC.

Referenced by tm2timestamp().

29 {
30  dt -= (tz * USECS_PER_SEC);
31  return dt;
32 } /* dt2local() */
#define USECS_PER_SEC
Definition: timestamp.h:94
static int dttofmtasc_replace ( timestamp ts,
date  dDate,
int  dow,
struct tm tm,
char *  output,
int *  pstr_len,
const char *  fmtstr 
)
static

Definition at line 312 of file timestamp.c.

References un_fmt_comb::char_val, days, fmtstr(), i, un_fmt_comb::int64_val, months, output(), pgtypes_date_months, pgtypes_date_weekdays_short, pgtypes_fmt_replace(), PGTYPES_TYPE_CHAR, PGTYPES_TYPE_INT64, PGTYPES_TYPE_NOTHING, PGTYPES_TYPE_STRING_CONSTANT, PGTYPES_TYPE_UINT, PGTYPES_TYPE_UINT_2_LS, PGTYPES_TYPE_UINT_2_LZ, PGTYPES_TYPE_UINT_3_LZ, SetEpochTimestamp(), un_fmt_comb::str_val, and un_fmt_comb::uint_val.

Referenced by PGTYPEStimestamp_fmt_asc().

314 {
315  union un_fmt_comb replace_val;
316  int replace_type;
317  int i;
318  const char *p = fmtstr;
319  char *q = output;
320 
321  while (*p)
322  {
323  if (*p == '%')
324  {
325  p++;
326  /* fix compiler warning */
327  replace_type = PGTYPES_TYPE_NOTHING;
328  switch (*p)
329  {
330  /* the abbreviated name of the day in the week */
331  /* XXX should be locale aware */
332  case 'a':
333  replace_val.str_val = pgtypes_date_weekdays_short[dow];
334  replace_type = PGTYPES_TYPE_STRING_CONSTANT;
335  break;
336  /* the full name of the day in the week */
337  /* XXX should be locale aware */
338  case 'A':
339  replace_val.str_val = days[dow];
340  replace_type = PGTYPES_TYPE_STRING_CONSTANT;
341  break;
342  /* the abbreviated name of the month */
343  /* XXX should be locale aware */
344  case 'b':
345  case 'h':
346  replace_val.str_val = months[tm->tm_mon];
347  replace_type = PGTYPES_TYPE_STRING_CONSTANT;
348  break;
349  /* the full name of the month */
350  /* XXX should be locale aware */
351  case 'B':
352  replace_val.str_val = pgtypes_date_months[tm->tm_mon];
353  replace_type = PGTYPES_TYPE_STRING_CONSTANT;
354  break;
355 
356  /*
357  * The preferred date and time representation for
358  * the current locale.
359  */
360  case 'c':
361  /* XXX */
362  break;
363  /* the century number with leading zeroes */
364  case 'C':
365  replace_val.uint_val = tm->tm_year / 100;
366  replace_type = PGTYPES_TYPE_UINT_2_LZ;
367  break;
368  /* day with leading zeroes (01 - 31) */
369  case 'd':
370  replace_val.uint_val = tm->tm_mday;
371  replace_type = PGTYPES_TYPE_UINT_2_LZ;
372  break;
373  /* the date in the format mm/dd/yy */
374  case 'D':
375 
376  /*
377  * ts, dDate, dow, tm is information about the timestamp
378  *
379  * q is the start of the current output buffer
380  *
381  * pstr_len is a pointer to the remaining size of output,
382  * i.e. the size of q
383  */
384  i = dttofmtasc_replace(ts, dDate, dow, tm,
385  q, pstr_len,
386  "%m/%d/%y");
387  if (i)
388  return i;
389  break;
390  /* day with leading spaces (01 - 31) */
391  case 'e':
392  replace_val.uint_val = tm->tm_mday;
393  replace_type = PGTYPES_TYPE_UINT_2_LS;
394  break;
395 
396  /*
397  * alternative format modifier
398  */
399  case 'E':
400  {
401  char tmp[4] = "%Ex";
402 
403  p++;
404  if (*p == '\0')
405  return -1;
406  tmp[2] = *p;
407 
408  /*
409  * strftime's month is 0 based, ours is 1 based
410  */
411  tm->tm_mon -= 1;
412  i = strftime(q, *pstr_len, tmp, tm);
413  if (i == 0)
414  return -1;
415  while (*q)
416  {
417  q++;
418  (*pstr_len)--;
419  }
420  tm->tm_mon += 1;
421  replace_type = PGTYPES_TYPE_NOTHING;
422  break;
423  }
424 
425  /*
426  * The ISO 8601 year with century as a decimal number. The
427  * 4-digit year corresponding to the ISO week number.
428  */
429  case 'G':
430  {
431  /* Keep compiler quiet - Don't use a literal format */
432  const char *fmt = "%G";
433 
434  tm->tm_mon -= 1;
435  i = strftime(q, *pstr_len, fmt, tm);
436  if (i == 0)
437  return -1;
438  while (*q)
439  {
440  q++;
441  (*pstr_len)--;
442  }
443  tm->tm_mon += 1;
444  replace_type = PGTYPES_TYPE_NOTHING;
445  }
446  break;
447 
448  /*
449  * Like %G, but without century, i.e., with a 2-digit year
450  * (00-99).
451  */
452  case 'g':
453  {
454  const char *fmt = "%g"; /* Keep compiler quiet about
455  * 2-digit year */
456 
457  tm->tm_mon -= 1;
458  i = strftime(q, *pstr_len, fmt, tm);
459  if (i == 0)
460  return -1;
461  while (*q)
462  {
463  q++;
464  (*pstr_len)--;
465  }
466  tm->tm_mon += 1;
467  replace_type = PGTYPES_TYPE_NOTHING;
468  }
469  break;
470  /* hour (24 hour clock) with leading zeroes */
471  case 'H':
472  replace_val.uint_val = tm->tm_hour;
473  replace_type = PGTYPES_TYPE_UINT_2_LZ;
474  break;
475  /* hour (12 hour clock) with leading zeroes */
476  case 'I':
477  replace_val.uint_val = tm->tm_hour % 12;
478  replace_type = PGTYPES_TYPE_UINT_2_LZ;
479  break;
480 
481  /*
482  * The day of the year as a decimal number with leading
483  * zeroes. It ranges from 001 to 366.
484  */
485  case 'j':
486  replace_val.uint_val = tm->tm_yday;
487  replace_type = PGTYPES_TYPE_UINT_3_LZ;
488  break;
489 
490  /*
491  * The hour (24 hour clock). Leading zeroes will be turned
492  * into spaces.
493  */
494  case 'k':
495  replace_val.uint_val = tm->tm_hour;
496  replace_type = PGTYPES_TYPE_UINT_2_LS;
497  break;
498 
499  /*
500  * The hour (12 hour clock). Leading zeroes will be turned
501  * into spaces.
502  */
503  case 'l':
504  replace_val.uint_val = tm->tm_hour % 12;
505  replace_type = PGTYPES_TYPE_UINT_2_LS;
506  break;
507  /* The month as a decimal number with a leading zero */
508  case 'm':
509  replace_val.uint_val = tm->tm_mon;
510  replace_type = PGTYPES_TYPE_UINT_2_LZ;
511  break;
512  /* The minute as a decimal number with a leading zero */
513  case 'M':
514  replace_val.uint_val = tm->tm_min;
515  replace_type = PGTYPES_TYPE_UINT_2_LZ;
516  break;
517  /* A newline character */
518  case 'n':
519  replace_val.char_val = '\n';
520  replace_type = PGTYPES_TYPE_CHAR;
521  break;
522  /* the AM/PM specifier (uppercase) */
523  /* XXX should be locale aware */
524  case 'p':
525  if (tm->tm_hour < 12)
526  replace_val.str_val = "AM";
527  else
528  replace_val.str_val = "PM";
529  replace_type = PGTYPES_TYPE_STRING_CONSTANT;
530  break;
531  /* the AM/PM specifier (lowercase) */
532  /* XXX should be locale aware */
533  case 'P':
534  if (tm->tm_hour < 12)
535  replace_val.str_val = "am";
536  else
537  replace_val.str_val = "pm";
538  replace_type = PGTYPES_TYPE_STRING_CONSTANT;
539  break;
540  /* the time in the format %I:%M:%S %p */
541  /* XXX should be locale aware */
542  case 'r':
543  i = dttofmtasc_replace(ts, dDate, dow, tm,
544  q, pstr_len,
545  "%I:%M:%S %p");
546  if (i)
547  return i;
548  break;
549  /* The time in 24 hour notation (%H:%M) */
550  case 'R':
551  i = dttofmtasc_replace(ts, dDate, dow, tm,
552  q, pstr_len,
553  "%H:%M");
554  if (i)
555  return i;
556  break;
557  /* The number of seconds since the Epoch (1970-01-01) */
558  case 's':
559  replace_val.int64_val = (*ts - SetEpochTimestamp()) / 1000000.0;
560  replace_type = PGTYPES_TYPE_INT64;
561  break;
562  /* seconds as a decimal number with leading zeroes */
563  case 'S':
564  replace_val.uint_val = tm->tm_sec;
565  replace_type = PGTYPES_TYPE_UINT_2_LZ;
566  break;
567  /* A tabulator */
568  case 't':
569  replace_val.char_val = '\t';
570  replace_type = PGTYPES_TYPE_CHAR;
571  break;
572  /* The time in 24 hour notation (%H:%M:%S) */
573  case 'T':
574  i = dttofmtasc_replace(ts, dDate, dow, tm,
575  q, pstr_len,
576  "%H:%M:%S");
577  if (i)
578  return i;
579  break;
580 
581  /*
582  * The day of the week as a decimal, Monday = 1, Sunday =
583  * 7
584  */
585  case 'u':
586  replace_val.uint_val = dow;
587  if (replace_val.uint_val == 0)
588  replace_val.uint_val = 7;
589  replace_type = PGTYPES_TYPE_UINT;
590  break;
591  /* The week number of the year as a decimal number */
592  case 'U':
593  tm->tm_mon -= 1;
594  i = strftime(q, *pstr_len, "%U", tm);
595  if (i == 0)
596  return -1;
597  while (*q)
598  {
599  q++;
600  (*pstr_len)--;
601  }
602  tm->tm_mon += 1;
603  replace_type = PGTYPES_TYPE_NOTHING;
604  break;
605 
606  /*
607  * The ISO 8601:1988 week number of the current year as a
608  * decimal number.
609  */
610  case 'V':
611  {
612  /* Keep compiler quiet - Don't use a literal format */
613  const char *fmt = "%V";
614 
615  i = strftime(q, *pstr_len, fmt, tm);
616  if (i == 0)
617  return -1;
618  while (*q)
619  {
620  q++;
621  (*pstr_len)--;
622  }
623  replace_type = PGTYPES_TYPE_NOTHING;
624  }
625  break;
626 
627  /*
628  * The day of the week as a decimal, Sunday being 0 and
629  * Monday 1.
630  */
631  case 'w':
632  replace_val.uint_val = dow;
633  replace_type = PGTYPES_TYPE_UINT;
634  break;
635  /* The week number of the year (another definition) */
636  case 'W':
637  tm->tm_mon -= 1;
638  i = strftime(q, *pstr_len, "%U", tm);
639  if (i == 0)
640  return -1;
641  while (*q)
642  {
643  q++;
644  (*pstr_len)--;
645  }
646  tm->tm_mon += 1;
647  replace_type = PGTYPES_TYPE_NOTHING;
648  break;
649 
650  /*
651  * The preferred date representation for the current
652  * locale without the time.
653  */
654  case 'x':
655  {
656  const char *fmt = "%x"; /* Keep compiler quiet about
657  * 2-digit year */
658 
659  tm->tm_mon -= 1;
660  i = strftime(q, *pstr_len, fmt, tm);
661  if (i == 0)
662  return -1;
663  while (*q)
664  {
665  q++;
666  (*pstr_len)--;
667  }
668  tm->tm_mon += 1;
669  replace_type = PGTYPES_TYPE_NOTHING;
670  }
671  break;
672 
673  /*
674  * The preferred time representation for the current
675  * locale without the date.
676  */
677  case 'X':
678  tm->tm_mon -= 1;
679  i = strftime(q, *pstr_len, "%X", tm);
680  if (i == 0)
681  return -1;
682  while (*q)
683  {
684  q++;
685  (*pstr_len)--;
686  }
687  tm->tm_mon += 1;
688  replace_type = PGTYPES_TYPE_NOTHING;
689  break;
690  /* The year without the century (2 digits, leading zeroes) */
691  case 'y':
692  replace_val.uint_val = tm->tm_year % 100;
693  replace_type = PGTYPES_TYPE_UINT_2_LZ;
694  break;
695  /* The year with the century (4 digits) */
696  case 'Y':
697  replace_val.uint_val = tm->tm_year;
698  replace_type = PGTYPES_TYPE_UINT;
699  break;
700  /* The time zone offset from GMT */
701  case 'z':
702  tm->tm_mon -= 1;
703  i = strftime(q, *pstr_len, "%z", tm);
704  if (i == 0)
705  return -1;
706  while (*q)
707  {
708  q++;
709  (*pstr_len)--;
710  }
711  tm->tm_mon += 1;
712  replace_type = PGTYPES_TYPE_NOTHING;
713  break;
714  /* The name or abbreviation of the time zone */
715  case 'Z':
716  tm->tm_mon -= 1;
717  i = strftime(q, *pstr_len, "%Z", tm);
718  if (i == 0)
719  return -1;
720  while (*q)
721  {
722  q++;
723  (*pstr_len)--;
724  }
725  tm->tm_mon += 1;
726  replace_type = PGTYPES_TYPE_NOTHING;
727  break;
728  /* A % sign */
729  case '%':
730  replace_val.char_val = '%';
731  replace_type = PGTYPES_TYPE_CHAR;
732  break;
733  case '\0':
734  /* fmtstr: foo%' - The string ends with a % sign */
735 
736  /*
737  * this is not compliant to the specification
738  */
739  return -1;
740  default:
741 
742  /*
743  * if we don't know the pattern, we just copy it
744  */
745  if (*pstr_len > 1)
746  {
747  *q = '%';
748  q++;
749  (*pstr_len)--;
750  if (*pstr_len > 1)
751  {
752  *q = *p;
753  q++;
754  (*pstr_len)--;
755  }
756  else
757  {
758  *q = '\0';
759  return -1;
760  }
761  *q = '\0';
762  }
763  else
764  return -1;
765  break;
766  }
767  i = pgtypes_fmt_replace(replace_val, replace_type, &q, pstr_len);
768  if (i)
769  return i;
770  }
771  else
772  {
773  if (*pstr_len > 1)
774  {
775  *q = *p;
776  (*pstr_len)--;
777  q++;
778  *q = '\0';
779  }
780  else
781  return -1;
782  }
783  p++;
784  }
785  return 0;
786 }
static int dttofmtasc_replace(timestamp *ts, date dDate, int dow, struct tm *tm, char *output, int *pstr_len, const char *fmtstr)
Definition: timestamp.c:312
#define PGTYPES_TYPE_CHAR
Definition: extern.h:13
static void output(uint64 loop_count)
int tm_hour
Definition: pgtime.h:29
char * pgtypes_date_weekdays_short[]
Definition: dt_common.c:501
static struct pg_tm tm
Definition: localtime.c:107
#define PGTYPES_TYPE_INT64
Definition: extern.h:15
const char *const months[]
Definition: datetime.c:66
int tm_mday
Definition: pgtime.h:30
int tm_mon
Definition: pgtime.h:31
const char *const days[]
Definition: datetime.c:69
#define PGTYPES_TYPE_UINT_3_LZ
Definition: extern.h:20
#define PGTYPES_TYPE_NOTHING
Definition: extern.h:10
static void fmtstr(char *value, int leftjust, int minlen, int maxwidth, int pointflag, PrintfTarget *target)
Definition: snprintf.c:794
char * pgtypes_date_months[]
Definition: dt_common.c:503
#define PGTYPES_TYPE_UINT_2_LS
Definition: extern.h:18
#define PGTYPES_TYPE_UINT_2_LZ
Definition: extern.h:17
#define PGTYPES_TYPE_STRING_CONSTANT
Definition: extern.h:12
int pgtypes_fmt_replace(union un_fmt_comb replace_val, int replace_type, char **output, int *pstr_len)
Definition: common.c:29
int tm_year
Definition: pgtime.h:32
int i
int tm_yday
Definition: pgtime.h:34
int tm_sec
Definition: pgtime.h:27
#define PGTYPES_TYPE_UINT
Definition: extern.h:16
int tm_min
Definition: pgtime.h:28
Timestamp SetEpochTimestamp(void)
Definition: timestamp.c:2003
static int EncodeSpecialTimestamp ( timestamp  dt,
char *  str 
)
static

Definition at line 196 of file timestamp.c.

References EARLY, FALSE, LATE, TIMESTAMP_IS_NOBEGIN, TIMESTAMP_IS_NOEND, and TRUE.

197 {
198  if (TIMESTAMP_IS_NOBEGIN(dt))
199  strcpy(str, EARLY);
200  else if (TIMESTAMP_IS_NOEND(dt))
201  strcpy(str, LATE);
202  else
203  return FALSE;
204 
205  return TRUE;
206 } /* EncodeSpecialTimestamp() */
#define LATE
Definition: datetime.h:41
#define FALSE
Definition: c.h:219
#define TIMESTAMP_IS_NOEND(j)
Definition: timestamp.h:120
#define TIMESTAMP_IS_NOBEGIN(j)
Definition: timestamp.h:115
#define TRUE
Definition: c.h:215
#define EARLY
Definition: datetime.h:40
int PGTYPEStimestamp_add_interval ( timestamp tin,
interval span,
timestamp tout 
)

Definition at line 870 of file timestamp.c.

References day_tab, isleap, interval::month, MONTHS_PER_YEAR, interval::time, timestamp2tm(), TIMESTAMP_NOT_FINITE, tm, tm2timestamp(), and pg_tm::tm_mon.

Referenced by main(), and PGTYPEStimestamp_sub_interval().

871 {
872  if (TIMESTAMP_NOT_FINITE(*tin))
873  *tout = *tin;
874 
875 
876  else
877  {
878  if (span->month != 0)
879  {
880  struct tm tt,
881  *tm = &tt;
882  fsec_t fsec;
883 
884 
885  if (timestamp2tm(*tin, NULL, tm, &fsec, NULL) != 0)
886  return -1;
887  tm->tm_mon += span->month;
888  if (tm->tm_mon > MONTHS_PER_YEAR)
889  {
890  tm->tm_year += (tm->tm_mon - 1) / MONTHS_PER_YEAR;
891  tm->tm_mon = (tm->tm_mon - 1) % MONTHS_PER_YEAR + 1;
892  }
893  else if (tm->tm_mon < 1)
894  {
895  tm->tm_year += tm->tm_mon / MONTHS_PER_YEAR - 1;
896  tm->tm_mon = tm->tm_mon % MONTHS_PER_YEAR + MONTHS_PER_YEAR;
897  }
898 
899 
900  /* adjust for end of month boundary problems... */
901  if (tm->tm_mday > day_tab[isleap(tm->tm_year)][tm->tm_mon - 1])
902  tm->tm_mday = (day_tab[isleap(tm->tm_year)][tm->tm_mon - 1]);
903 
904 
905  if (tm2timestamp(tm, fsec, NULL, tin) != 0)
906  return -1;
907  }
908 
909 
910  *tin += span->time;
911  *tout = *tin;
912  }
913  return 0;
914 
915 }
#define isleap(y)
Definition: datetime.h:273
int timestamp2tm(Timestamp dt, int *tzp, struct pg_tm *tm, fsec_t *fsec, const char **tzn, pg_tz *attimezone)
Definition: timestamp.c:1758
static struct pg_tm tm
Definition: localtime.c:107
#define MONTHS_PER_YEAR
Definition: timestamp.h:69
#define TIMESTAMP_NOT_FINITE(j)
Definition: timestamp.h:122
int tm_mon
Definition: pgtime.h:31
int32 fsec_t
Definition: timestamp.h:41
const int day_tab[2][13]
Definition: datetime.c:60
int tm2timestamp(struct pg_tm *tm, fsec_t fsec, int *tzp, Timestamp *result)
Definition: timestamp.c:1854
void PGTYPEStimestamp_current ( timestamp ts)

Definition at line 301 of file timestamp.c.

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

Referenced by dtcurrent(), and main().

302 {
303  struct tm tm;
304 
306  if (errno == 0)
307  tm2timestamp(&tm, 0, NULL, ts);
308  return;
309 }
void GetCurrentDateTime(struct pg_tm *tm)
Definition: datetime.c:370
static struct pg_tm tm
Definition: localtime.c:107
int tm2timestamp(struct pg_tm *tm, fsec_t fsec, int *tzp, Timestamp *result)
Definition: timestamp.c:1854
int PGTYPEStimestamp_defmt_asc ( char *  str,
const char *  fmt,
timestamp d 
)

Definition at line 818 of file timestamp.c.

References free, i, pgtypes_strdup(), and PGTYPEStimestamp_defmt_scan().

Referenced by dtcvfmtasc(), and main().

819 {
820  int year,
821  month,
822  day;
823  int hour,
824  minute,
825  second;
826  int tz;
827 
828  int i;
829  char *mstr;
830  char *mfmt;
831 
832  if (!fmt)
833  fmt = "%Y-%m-%d %H:%M:%S";
834  if (!fmt[0])
835  return 1;
836 
837  mstr = pgtypes_strdup(str);
838  mfmt = pgtypes_strdup(fmt);
839 
840  /*
841  * initialize with impossible values so that we can see if the fields
842  * where specified at all
843  */
844  /* XXX ambiguity with 1 BC for year? */
845  year = -1;
846  month = -1;
847  day = -1;
848  hour = 0;
849  minute = -1;
850  second = -1;
851  tz = 0;
852 
853  i = PGTYPEStimestamp_defmt_scan(&mstr, mfmt, d, &year, &month, &day, &hour, &minute, &second, &tz);
854  free(mstr);
855  free(mfmt);
856  return i;
857 }
char * pgtypes_strdup(const char *str)
Definition: common.c:19
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
#define free(a)
Definition: header.h:65
int i
int PGTYPEStimestamp_fmt_asc ( timestamp ts,
char *  output,
int  str_len,
const char *  fmtstr 
)

Definition at line 790 of file timestamp.c.

References dttofmtasc_replace(), PGTYPESdate_dayofweek(), PGTYPESdate_from_timestamp(), timestamp2tm(), and tm.

Referenced by dttofmtasc(), and main().

791 {
792  struct tm tm;
793  fsec_t fsec;
794  date dDate;
795  int dow;
796 
797  dDate = PGTYPESdate_from_timestamp(*ts);
798  dow = PGTYPESdate_dayofweek(dDate);
799  timestamp2tm(*ts, NULL, &tm, &fsec, NULL);
800 
801  return dttofmtasc_replace(ts, dDate, dow, &tm, output, &str_len, fmtstr);
802 }
static int dttofmtasc_replace(timestamp *ts, date dDate, int dow, struct tm *tm, char *output, int *pstr_len, const char *fmtstr)
Definition: timestamp.c:312
static void output(uint64 loop_count)
int timestamp2tm(Timestamp dt, int *tzp, struct pg_tm *tm, fsec_t *fsec, const char **tzn, pg_tz *attimezone)
Definition: timestamp.c:1758
long date
Definition: pgtypes_date.h:8
static struct pg_tm tm
Definition: localtime.c:107
int PGTYPESdate_dayofweek(date)
Definition: datetime.c:139
int32 fsec_t
Definition: timestamp.h:41
static void fmtstr(char *value, int leftjust, int minlen, int maxwidth, int pointflag, PrintfTarget *target)
Definition: snprintf.c:794
date PGTYPESdate_from_timestamp(timestamp)
Definition: datetime.c:32
timestamp PGTYPEStimestamp_from_asc ( char *  str,
char **  endptr 
)

Definition at line 209 of file timestamp.c.

References DecodeDateTime(), DTK_DATE, DTK_EARLY, DTK_EPOCH, DTK_INVALID, DTK_LATE, MAXDATEFIELDS, MAXDATELEN, ParseDateTime(), PGTYPES_TS_BAD_TIMESTAMP, SetEpochTimestamp(), TIMESTAMP_NOBEGIN, TIMESTAMP_NOEND, tm, and tm2timestamp().

Referenced by dtcvasc(), ecpg_get_data(), and main().

210 {
211  timestamp result;
212  int64 noresult = 0;
213  fsec_t fsec;
214  struct tm tt,
215  *tm = &tt;
216  int dtype;
217  int nf;
218  char *field[MAXDATEFIELDS];
219  int ftype[MAXDATEFIELDS];
220  char lowstr[MAXDATELEN + MAXDATEFIELDS];
221  char *realptr;
222  char **ptr = (endptr != NULL) ? endptr : &realptr;
223 
224  if (strlen(str) > MAXDATELEN)
225  {
226  errno = PGTYPES_TS_BAD_TIMESTAMP;
227  return noresult;
228  }
229 
230  if (ParseDateTime(str, lowstr, field, ftype, &nf, ptr) != 0 ||
231  DecodeDateTime(field, ftype, nf, &dtype, tm, &fsec, 0) != 0)
232  {
233  errno = PGTYPES_TS_BAD_TIMESTAMP;
234  return noresult;
235  }
236 
237  switch (dtype)
238  {
239  case DTK_DATE:
240  if (tm2timestamp(tm, fsec, NULL, &result) != 0)
241  {
242  errno = PGTYPES_TS_BAD_TIMESTAMP;
243  return noresult;
244  }
245  break;
246 
247  case DTK_EPOCH:
248  result = SetEpochTimestamp();
249  break;
250 
251  case DTK_LATE:
252  TIMESTAMP_NOEND(result);
253  break;
254 
255  case DTK_EARLY:
256  TIMESTAMP_NOBEGIN(result);
257  break;
258 
259  case DTK_INVALID:
260  errno = PGTYPES_TS_BAD_TIMESTAMP;
261  return noresult;
262 
263  default:
264  errno = PGTYPES_TS_BAD_TIMESTAMP;
265  return noresult;
266  }
267 
268  /* AdjustTimestampForTypmod(&result, typmod); */
269 
270  /*
271  * Since it's difficult to test for noresult, make sure errno is 0 if no
272  * error occurred.
273  */
274  errno = 0;
275  return result;
276 }
#define MAXDATELEN
Definition: datetime.h:203
#define TIMESTAMP_NOEND(j)
Definition: timestamp.h:117
int64 timestamp
#define DTK_INVALID
Definition: datetime.h:151
static struct pg_tm tm
Definition: localtime.c:107
int DecodeDateTime(char **field, int *ftype, int nf, int *dtype, struct pg_tm *tm, fsec_t *fsec, int *tzp)
Definition: datetime.c:783
#define TIMESTAMP_NOBEGIN(j)
Definition: timestamp.h:112
int32 fsec_t
Definition: timestamp.h:41
#define DTK_LATE
Definition: datetime.h:154
int tm2timestamp(struct pg_tm *tm, fsec_t fsec, int *tzp, Timestamp *result)
Definition: timestamp.c:1854
#define DTK_EARLY
Definition: datetime.h:153
#define MAXDATEFIELDS
Definition: datetime.h:205
#define DTK_EPOCH
Definition: datetime.h:155
int ParseDateTime(const char *timestr, char *workbuf, size_t buflen, char **field, int *ftype, int maxfields, int *numfields)
Definition: datetime.c:562
#define PGTYPES_TS_BAD_TIMESTAMP
Definition: pgtypes_error.h:15
#define DTK_DATE
Definition: datetime.h:145
Timestamp SetEpochTimestamp(void)
Definition: timestamp.c:2003
int PGTYPEStimestamp_sub ( timestamp ts1,
timestamp ts2,
interval iv 
)

Definition at line 805 of file timestamp.c.

References interval::month, PGTYPES_TS_ERR_EINFTIME, interval::time, and TIMESTAMP_NOT_FINITE.

Referenced by dtsub().

806 {
807  if (TIMESTAMP_NOT_FINITE(*ts1) || TIMESTAMP_NOT_FINITE(*ts2))
809  else
810  iv->time = (*ts1 - *ts2);
811 
812  iv->month = 0;
813 
814  return 0;
815 }
#define PGTYPES_TS_ERR_EINFTIME
Definition: pgtypes_error.h:16
#define TIMESTAMP_NOT_FINITE(j)
Definition: timestamp.h:122
int PGTYPEStimestamp_sub_interval ( timestamp tin,
interval span,
timestamp tout 
)

Definition at line 929 of file timestamp.c.

References interval::month, PGTYPEStimestamp_add_interval(), and interval::time.

930 {
931  interval tspan;
932 
933  tspan.month = -span->month;
934  tspan.time = -span->time;
935 
936 
937  return PGTYPEStimestamp_add_interval(tin, &tspan, tout);
938 }
int PGTYPEStimestamp_add_interval(timestamp *tin, interval *span, timestamp *tout)
Definition: timestamp.c:870
char* PGTYPEStimestamp_to_asc ( timestamp  tstamp)

Definition at line 279 of file timestamp.c.

References buf, DateStyle, EncodeDateTime(), EncodeSpecialTimestamp(), MAXDATELEN, pgtypes_strdup(), PGTYPES_TS_BAD_TIMESTAMP, timestamp2tm(), TIMESTAMP_NOT_FINITE, and tm.

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

280 {
281  struct tm tt,
282  *tm = &tt;
283  char buf[MAXDATELEN + 1];
284  fsec_t fsec;
285  int DateStyle = 1; /* this defaults to ISO_DATES, shall we make
286  * it an option? */
287 
288  if (TIMESTAMP_NOT_FINITE(tstamp))
289  EncodeSpecialTimestamp(tstamp, buf);
290  else if (timestamp2tm(tstamp, NULL, tm, &fsec, NULL) == 0)
291  EncodeDateTime(tm, fsec, false, 0, NULL, DateStyle, buf, 0);
292  else
293  {
294  errno = PGTYPES_TS_BAD_TIMESTAMP;
295  return NULL;
296  }
297  return pgtypes_strdup(buf);
298 }
#define MAXDATELEN
Definition: datetime.h:203
int timestamp2tm(Timestamp dt, int *tzp, struct pg_tm *tm, fsec_t *fsec, const char **tzn, pg_tz *attimezone)
Definition: timestamp.c:1758
void EncodeSpecialTimestamp(Timestamp dt, char *str)
Definition: timestamp.c:1523
static struct pg_tm tm
Definition: localtime.c:107
char * pgtypes_strdup(const char *str)
Definition: common.c:19
#define TIMESTAMP_NOT_FINITE(j)
Definition: timestamp.h:122
static char * buf
Definition: pg_test_fsync.c:67
void EncodeDateTime(struct pg_tm *tm, fsec_t fsec, bool print_tz, int tz, const char *tzn, int style, char *str)
Definition: datetime.c:3999
int32 fsec_t
Definition: timestamp.h:41
int DateStyle
Definition: globals.c:107
#define PGTYPES_TS_BAD_TIMESTAMP
Definition: pgtypes_error.h:15
static timestamp SetEpochTimestamp ( void  )
static

Definition at line 73 of file timestamp.c.

References GetEpochTime(), tm, and tm2timestamp().

74 {
75  int64 noresult = 0;
76  timestamp dt;
77  struct tm tt,
78  *tm = &tt;
79 
80  if (GetEpochTime(tm) < 0)
81  return noresult;
82 
83  tm2timestamp(tm, 0, NULL, &dt);
84  return dt;
85 } /* SetEpochTimestamp() */
int64 timestamp
static struct pg_tm tm
Definition: localtime.c:107
int tm2timestamp(struct pg_tm *tm, fsec_t fsec, int *tzp, Timestamp *result)
Definition: timestamp.c:1854
void GetEpochTime(struct pg_tm *tm)
Definition: timestamp.c:1984
static int64 time2t ( const int  hour,
const int  min,
const int  sec,
const fsec_t  fsec 
)
static

Definition at line 22 of file timestamp.c.

References MINS_PER_HOUR, SECS_PER_MINUTE, and USECS_PER_SEC.

Referenced by tm2timestamp().

23 {
24  return (((((hour * MINS_PER_HOUR) + min) * SECS_PER_MINUTE) + sec) * USECS_PER_SEC) + fsec;
25 } /* time2t() */
#define USECS_PER_SEC
Definition: timestamp.h:94
#define MINS_PER_HOUR
Definition: timestamp.h:89
#define SECS_PER_MINUTE
Definition: timestamp.h:88
static int timestamp2tm ( timestamp  dt,
int *  tzp,
struct tm tm,
fsec_t fsec,
const char **  tzn 
)
static

Definition at line 99 of file timestamp.c.

References date2j(), dt2time(), IS_VALID_UTIME, j2date(), SECS_PER_HOUR, TIMEZONE_GLOBAL, TMODULO, TZNAME_GLOBAL, USECS_PER_DAY, and USECS_PER_SEC.

100 {
101  int64 dDate,
102  date0;
103  int64 time;
104 #if defined(HAVE_TM_ZONE) || defined(HAVE_INT_TIMEZONE)
105  time_t utime;
106  struct tm *tx;
107 #endif
108 
109  date0 = date2j(2000, 1, 1);
110 
111  time = dt;
112  TMODULO(time, dDate, USECS_PER_DAY);
113 
114  if (time < INT64CONST(0))
115  {
116  time += USECS_PER_DAY;
117  dDate -= 1;
118  }
119 
120  /* add offset to go from J2000 back to standard Julian date */
121  dDate += date0;
122 
123  /* Julian day routine does not work for negative Julian days */
124  if (dDate < 0 || dDate > (timestamp) INT_MAX)
125  return -1;
126 
127  j2date((int) dDate, &tm->tm_year, &tm->tm_mon, &tm->tm_mday);
128  dt2time(time, &tm->tm_hour, &tm->tm_min, &tm->tm_sec, fsec);
129 
130  if (tzp != NULL)
131  {
132  /*
133  * Does this fall within the capabilities of the localtime()
134  * interface? Then use this to rotate to the local time zone.
135  */
137  {
138 #if defined(HAVE_TM_ZONE) || defined(HAVE_INT_TIMEZONE)
139 
140  utime = dt / USECS_PER_SEC +
141  ((date0 - date2j(1970, 1, 1)) * INT64CONST(86400));
142 
143  tx = localtime(&utime);
144  tm->tm_year = tx->tm_year + 1900;
145  tm->tm_mon = tx->tm_mon + 1;
146  tm->tm_mday = tx->tm_mday;
147  tm->tm_hour = tx->tm_hour;
148  tm->tm_min = tx->tm_min;
149  tm->tm_isdst = tx->tm_isdst;
150 
151 #if defined(HAVE_TM_ZONE)
152  tm->tm_gmtoff = tx->tm_gmtoff;
153  tm->tm_zone = tx->tm_zone;
154 
155  *tzp = -tm->tm_gmtoff; /* tm_gmtoff is Sun/DEC-ism */
156  if (tzn != NULL)
157  *tzn = tm->tm_zone;
158 #elif defined(HAVE_INT_TIMEZONE)
160  if (tzn != NULL)
161  *tzn = TZNAME_GLOBAL[(tm->tm_isdst > 0)];
162 #endif
163 #else /* not (HAVE_TM_ZONE || HAVE_INT_TIMEZONE) */
164  *tzp = 0;
165  /* Mark this as *no* time zone available */
166  tm->tm_isdst = -1;
167  if (tzn != NULL)
168  *tzn = NULL;
169 #endif
170  }
171  else
172  {
173  *tzp = 0;
174  /* Mark this as *no* time zone available */
175  tm->tm_isdst = -1;
176  if (tzn != NULL)
177  *tzn = NULL;
178  }
179  }
180  else
181  {
182  tm->tm_isdst = -1;
183  if (tzn != NULL)
184  *tzn = NULL;
185  }
186 
187  tm->tm_yday = dDate - date2j(tm->tm_year, 1, 1) + 1;
188 
189  return 0;
190 } /* timestamp2tm() */
int tm_isdst
Definition: pgtime.h:35
#define USECS_PER_SEC
Definition: timestamp.h:94
int64 timestamp
int tm_hour
Definition: pgtime.h:29
#define TZNAME_GLOBAL
Definition: port.h:226
#define TIMEZONE_GLOBAL
Definition: port.h:225
long int tm_gmtoff
Definition: pgtime.h:36
static struct pg_tm tm
Definition: localtime.c:107
int tm_mday
Definition: pgtime.h:30
#define IS_VALID_UTIME(y, m, d)
Definition: dt.h:298
int tm_mon
Definition: pgtime.h:31
#define USECS_PER_DAY
Definition: timestamp.h:91
const char * tm_zone
Definition: pgtime.h:37
void j2date(int jd, int *year, int *month, int *day)
Definition: datetime.c:317
#define SECS_PER_HOUR
Definition: timestamp.h:87
int date2j(int y, int m, int d)
Definition: datetime.c:292
void dt2time(Timestamp jd, int *hour, int *min, int *sec, fsec_t *fsec)
Definition: timestamp.c:1731
int tm_year
Definition: pgtime.h:32
int tm_yday
Definition: pgtime.h:34
int tm_sec
Definition: pgtime.h:27
int tm_min
Definition: pgtime.h:28
#define TMODULO(t, q, u)
Definition: datetime.h:251
int tm2timestamp ( struct tm tm,
fsec_t  fsec,
int *  tzp,
timestamp result 
)

Definition at line 42 of file timestamp.c.

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

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