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 double 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 36 of file timestamp.c.

References USECS_PER_SEC.

Referenced by tm2timestamp().

37 {
38 #ifdef HAVE_INT64_TIMESTAMP
39  dt -= (tz * USECS_PER_SEC);
40 #else
41  dt -= tz;
42 #endif
43  return dt;
44 } /* dt2local() */
#define USECS_PER_SEC
Definition: timestamp.h:106
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 389 of file timestamp.c.

References un_fmt_comb::char_val, days, un_fmt_comb::double_val, fmtstr(), i, un_fmt_comb::int64_val, months, output(), pgtypes_date_months, pgtypes_date_weekdays_short, pgtypes_fmt_replace(), PGTYPES_TYPE_CHAR, PGTYPES_TYPE_DOUBLE_NF, 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().

391 {
392  union un_fmt_comb replace_val;
393  int replace_type;
394  int i;
395  const char *p = fmtstr;
396  char *q = output;
397 
398  while (*p)
399  {
400  if (*p == '%')
401  {
402  p++;
403  /* fix compiler warning */
404  replace_type = PGTYPES_TYPE_NOTHING;
405  switch (*p)
406  {
407  /* the abbreviated name of the day in the week */
408  /* XXX should be locale aware */
409  case 'a':
410  replace_val.str_val = pgtypes_date_weekdays_short[dow];
411  replace_type = PGTYPES_TYPE_STRING_CONSTANT;
412  break;
413  /* the full name of the day in the week */
414  /* XXX should be locale aware */
415  case 'A':
416  replace_val.str_val = days[dow];
417  replace_type = PGTYPES_TYPE_STRING_CONSTANT;
418  break;
419  /* the abbreviated name of the month */
420  /* XXX should be locale aware */
421  case 'b':
422  case 'h':
423  replace_val.str_val = months[tm->tm_mon];
424  replace_type = PGTYPES_TYPE_STRING_CONSTANT;
425  break;
426  /* the full name of the month */
427  /* XXX should be locale aware */
428  case 'B':
429  replace_val.str_val = pgtypes_date_months[tm->tm_mon];
430  replace_type = PGTYPES_TYPE_STRING_CONSTANT;
431  break;
432 
433  /*
434  * The preferred date and time representation for
435  * the current locale.
436  */
437  case 'c':
438  /* XXX */
439  break;
440  /* the century number with leading zeroes */
441  case 'C':
442  replace_val.uint_val = tm->tm_year / 100;
443  replace_type = PGTYPES_TYPE_UINT_2_LZ;
444  break;
445  /* day with leading zeroes (01 - 31) */
446  case 'd':
447  replace_val.uint_val = tm->tm_mday;
448  replace_type = PGTYPES_TYPE_UINT_2_LZ;
449  break;
450  /* the date in the format mm/dd/yy */
451  case 'D':
452 
453  /*
454  * ts, dDate, dow, tm is information about the timestamp
455  *
456  * q is the start of the current output buffer
457  *
458  * pstr_len is a pointer to the remaining size of output,
459  * i.e. the size of q
460  */
461  i = dttofmtasc_replace(ts, dDate, dow, tm,
462  q, pstr_len,
463  "%m/%d/%y");
464  if (i)
465  return i;
466  break;
467  /* day with leading spaces (01 - 31) */
468  case 'e':
469  replace_val.uint_val = tm->tm_mday;
470  replace_type = PGTYPES_TYPE_UINT_2_LS;
471  break;
472 
473  /*
474  * alternative format modifier
475  */
476  case 'E':
477  {
478  char tmp[4] = "%Ex";
479 
480  p++;
481  if (*p == '\0')
482  return -1;
483  tmp[2] = *p;
484 
485  /*
486  * strftime's month is 0 based, ours is 1 based
487  */
488  tm->tm_mon -= 1;
489  i = strftime(q, *pstr_len, tmp, tm);
490  if (i == 0)
491  return -1;
492  while (*q)
493  {
494  q++;
495  (*pstr_len)--;
496  }
497  tm->tm_mon += 1;
498  replace_type = PGTYPES_TYPE_NOTHING;
499  break;
500  }
501 
502  /*
503  * The ISO 8601 year with century as a decimal number. The
504  * 4-digit year corresponding to the ISO week number.
505  */
506  case 'G':
507  {
508  /* Keep compiler quiet - Don't use a literal format */
509  const char *fmt = "%G";
510 
511  tm->tm_mon -= 1;
512  i = strftime(q, *pstr_len, fmt, tm);
513  if (i == 0)
514  return -1;
515  while (*q)
516  {
517  q++;
518  (*pstr_len)--;
519  }
520  tm->tm_mon += 1;
521  replace_type = PGTYPES_TYPE_NOTHING;
522  }
523  break;
524 
525  /*
526  * Like %G, but without century, i.e., with a 2-digit year
527  * (00-99).
528  */
529  case 'g':
530  {
531  const char *fmt = "%g"; /* Keep compiler quiet about
532  * 2-digit year */
533 
534  tm->tm_mon -= 1;
535  i = strftime(q, *pstr_len, fmt, tm);
536  if (i == 0)
537  return -1;
538  while (*q)
539  {
540  q++;
541  (*pstr_len)--;
542  }
543  tm->tm_mon += 1;
544  replace_type = PGTYPES_TYPE_NOTHING;
545  }
546  break;
547  /* hour (24 hour clock) with leading zeroes */
548  case 'H':
549  replace_val.uint_val = tm->tm_hour;
550  replace_type = PGTYPES_TYPE_UINT_2_LZ;
551  break;
552  /* hour (12 hour clock) with leading zeroes */
553  case 'I':
554  replace_val.uint_val = tm->tm_hour % 12;
555  replace_type = PGTYPES_TYPE_UINT_2_LZ;
556  break;
557 
558  /*
559  * The day of the year as a decimal number with leading
560  * zeroes. It ranges from 001 to 366.
561  */
562  case 'j':
563  replace_val.uint_val = tm->tm_yday;
564  replace_type = PGTYPES_TYPE_UINT_3_LZ;
565  break;
566 
567  /*
568  * The hour (24 hour clock). Leading zeroes will be turned
569  * into spaces.
570  */
571  case 'k':
572  replace_val.uint_val = tm->tm_hour;
573  replace_type = PGTYPES_TYPE_UINT_2_LS;
574  break;
575 
576  /*
577  * The hour (12 hour clock). Leading zeroes will be turned
578  * into spaces.
579  */
580  case 'l':
581  replace_val.uint_val = tm->tm_hour % 12;
582  replace_type = PGTYPES_TYPE_UINT_2_LS;
583  break;
584  /* The month as a decimal number with a leading zero */
585  case 'm':
586  replace_val.uint_val = tm->tm_mon;
587  replace_type = PGTYPES_TYPE_UINT_2_LZ;
588  break;
589  /* The minute as a decimal number with a leading zero */
590  case 'M':
591  replace_val.uint_val = tm->tm_min;
592  replace_type = PGTYPES_TYPE_UINT_2_LZ;
593  break;
594  /* A newline character */
595  case 'n':
596  replace_val.char_val = '\n';
597  replace_type = PGTYPES_TYPE_CHAR;
598  break;
599  /* the AM/PM specifier (uppercase) */
600  /* XXX should be locale aware */
601  case 'p':
602  if (tm->tm_hour < 12)
603  replace_val.str_val = "AM";
604  else
605  replace_val.str_val = "PM";
606  replace_type = PGTYPES_TYPE_STRING_CONSTANT;
607  break;
608  /* the AM/PM specifier (lowercase) */
609  /* XXX should be locale aware */
610  case 'P':
611  if (tm->tm_hour < 12)
612  replace_val.str_val = "am";
613  else
614  replace_val.str_val = "pm";
615  replace_type = PGTYPES_TYPE_STRING_CONSTANT;
616  break;
617  /* the time in the format %I:%M:%S %p */
618  /* XXX should be locale aware */
619  case 'r':
620  i = dttofmtasc_replace(ts, dDate, dow, tm,
621  q, pstr_len,
622  "%I:%M:%S %p");
623  if (i)
624  return i;
625  break;
626  /* The time in 24 hour notation (%H:%M) */
627  case 'R':
628  i = dttofmtasc_replace(ts, dDate, dow, tm,
629  q, pstr_len,
630  "%H:%M");
631  if (i)
632  return i;
633  break;
634  /* The number of seconds since the Epoch (1970-01-01) */
635  case 's':
636 #ifdef HAVE_INT64_TIMESTAMP
637  replace_val.int64_val = (*ts - SetEpochTimestamp()) / 1000000.0;
638  replace_type = PGTYPES_TYPE_INT64;
639 #else
640  replace_val.double_val = *ts - SetEpochTimestamp();
641  replace_type = PGTYPES_TYPE_DOUBLE_NF;
642 #endif
643  break;
644  /* seconds as a decimal number with leading zeroes */
645  case 'S':
646  replace_val.uint_val = tm->tm_sec;
647  replace_type = PGTYPES_TYPE_UINT_2_LZ;
648  break;
649  /* A tabulator */
650  case 't':
651  replace_val.char_val = '\t';
652  replace_type = PGTYPES_TYPE_CHAR;
653  break;
654  /* The time in 24 hour notation (%H:%M:%S) */
655  case 'T':
656  i = dttofmtasc_replace(ts, dDate, dow, tm,
657  q, pstr_len,
658  "%H:%M:%S");
659  if (i)
660  return i;
661  break;
662 
663  /*
664  * The day of the week as a decimal, Monday = 1, Sunday =
665  * 7
666  */
667  case 'u':
668  replace_val.uint_val = dow;
669  if (replace_val.uint_val == 0)
670  replace_val.uint_val = 7;
671  replace_type = PGTYPES_TYPE_UINT;
672  break;
673  /* The week number of the year as a decimal number */
674  case 'U':
675  tm->tm_mon -= 1;
676  i = strftime(q, *pstr_len, "%U", tm);
677  if (i == 0)
678  return -1;
679  while (*q)
680  {
681  q++;
682  (*pstr_len)--;
683  }
684  tm->tm_mon += 1;
685  replace_type = PGTYPES_TYPE_NOTHING;
686  break;
687 
688  /*
689  * The ISO 8601:1988 week number of the current year as a
690  * decimal number.
691  */
692  case 'V':
693  {
694  /* Keep compiler quiet - Don't use a literal format */
695  const char *fmt = "%V";
696 
697  i = strftime(q, *pstr_len, fmt, tm);
698  if (i == 0)
699  return -1;
700  while (*q)
701  {
702  q++;
703  (*pstr_len)--;
704  }
705  replace_type = PGTYPES_TYPE_NOTHING;
706  }
707  break;
708 
709  /*
710  * The day of the week as a decimal, Sunday being 0 and
711  * Monday 1.
712  */
713  case 'w':
714  replace_val.uint_val = dow;
715  replace_type = PGTYPES_TYPE_UINT;
716  break;
717  /* The week number of the year (another definition) */
718  case 'W':
719  tm->tm_mon -= 1;
720  i = strftime(q, *pstr_len, "%U", tm);
721  if (i == 0)
722  return -1;
723  while (*q)
724  {
725  q++;
726  (*pstr_len)--;
727  }
728  tm->tm_mon += 1;
729  replace_type = PGTYPES_TYPE_NOTHING;
730  break;
731 
732  /*
733  * The preferred date representation for the current
734  * locale without the time.
735  */
736  case 'x':
737  {
738  const char *fmt = "%x"; /* Keep compiler quiet about
739  * 2-digit year */
740 
741  tm->tm_mon -= 1;
742  i = strftime(q, *pstr_len, fmt, tm);
743  if (i == 0)
744  return -1;
745  while (*q)
746  {
747  q++;
748  (*pstr_len)--;
749  }
750  tm->tm_mon += 1;
751  replace_type = PGTYPES_TYPE_NOTHING;
752  }
753  break;
754 
755  /*
756  * The preferred time representation for the current
757  * locale without the date.
758  */
759  case 'X':
760  tm->tm_mon -= 1;
761  i = strftime(q, *pstr_len, "%X", tm);
762  if (i == 0)
763  return -1;
764  while (*q)
765  {
766  q++;
767  (*pstr_len)--;
768  }
769  tm->tm_mon += 1;
770  replace_type = PGTYPES_TYPE_NOTHING;
771  break;
772  /* The year without the century (2 digits, leading zeroes) */
773  case 'y':
774  replace_val.uint_val = tm->tm_year % 100;
775  replace_type = PGTYPES_TYPE_UINT_2_LZ;
776  break;
777  /* The year with the century (4 digits) */
778  case 'Y':
779  replace_val.uint_val = tm->tm_year;
780  replace_type = PGTYPES_TYPE_UINT;
781  break;
782  /* The time zone offset from GMT */
783  case 'z':
784  tm->tm_mon -= 1;
785  i = strftime(q, *pstr_len, "%z", tm);
786  if (i == 0)
787  return -1;
788  while (*q)
789  {
790  q++;
791  (*pstr_len)--;
792  }
793  tm->tm_mon += 1;
794  replace_type = PGTYPES_TYPE_NOTHING;
795  break;
796  /* The name or abbreviation of the time zone */
797  case 'Z':
798  tm->tm_mon -= 1;
799  i = strftime(q, *pstr_len, "%Z", tm);
800  if (i == 0)
801  return -1;
802  while (*q)
803  {
804  q++;
805  (*pstr_len)--;
806  }
807  tm->tm_mon += 1;
808  replace_type = PGTYPES_TYPE_NOTHING;
809  break;
810  /* A % sign */
811  case '%':
812  replace_val.char_val = '%';
813  replace_type = PGTYPES_TYPE_CHAR;
814  break;
815  case '\0':
816  /* fmtstr: foo%' - The string ends with a % sign */
817 
818  /*
819  * this is not compliant to the specification
820  */
821  return -1;
822  default:
823 
824  /*
825  * if we don't know the pattern, we just copy it
826  */
827  if (*pstr_len > 1)
828  {
829  *q = '%';
830  q++;
831  (*pstr_len)--;
832  if (*pstr_len > 1)
833  {
834  *q = *p;
835  q++;
836  (*pstr_len)--;
837  }
838  else
839  {
840  *q = '\0';
841  return -1;
842  }
843  *q = '\0';
844  }
845  else
846  return -1;
847  break;
848  }
849  i = pgtypes_fmt_replace(replace_val, replace_type, &q, pstr_len);
850  if (i)
851  return i;
852  }
853  else
854  {
855  if (*pstr_len > 1)
856  {
857  *q = *p;
858  (*pstr_len)--;
859  q++;
860  *q = '\0';
861  }
862  else
863  return -1;
864  }
865  p++;
866  }
867  return 0;
868 }
static int dttofmtasc_replace(timestamp *ts, date dDate, int dow, struct tm *tm, char *output, int *pstr_len, const char *fmtstr)
Definition: timestamp.c:389
#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
#define PGTYPES_TYPE_DOUBLE_NF
Definition: extern.h:14
static struct pg_tm tm
Definition: localtime.c:103
#define PGTYPES_TYPE_INT64
Definition: extern.h:15
const char *const months[]
Definition: datetime.c:71
int tm_mday
Definition: pgtime.h:30
int tm_mon
Definition: pgtime.h:31
const char *const days[]
Definition: datetime.c:74
#define PGTYPES_TYPE_UINT_3_LZ
Definition: extern.h:21
#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:804
char * pgtypes_date_months[]
Definition: dt_common.c:503
#define PGTYPES_TYPE_UINT_2_LS
Definition: extern.h:19
#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:2274
static int EncodeSpecialTimestamp ( timestamp  dt,
char *  str 
)
static

Definition at line 268 of file timestamp.c.

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

269 {
270  if (TIMESTAMP_IS_NOBEGIN(dt))
271  strcpy(str, EARLY);
272  else if (TIMESTAMP_IS_NOEND(dt))
273  strcpy(str, LATE);
274  else
275  return FALSE;
276 
277  return TRUE;
278 } /* EncodeSpecialTimestamp() */
#define LATE
Definition: datetime.h:41
#define FALSE
Definition: c.h:218
#define TIMESTAMP_IS_NOEND(j)
Definition: timestamp.h:142
#define TIMESTAMP_IS_NOBEGIN(j)
Definition: timestamp.h:137
#define TRUE
Definition: c.h:214
#define EARLY
Definition: datetime.h:40
int PGTYPEStimestamp_add_interval ( timestamp tin,
interval span,
timestamp tout 
)

Definition at line 952 of file timestamp.c.

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

Referenced by main(), and PGTYPEStimestamp_sub_interval().

953 {
954  if (TIMESTAMP_NOT_FINITE(*tin))
955  *tout = *tin;
956 
957 
958  else
959  {
960  if (span->month != 0)
961  {
962  struct tm tt,
963  *tm = &tt;
964  fsec_t fsec;
965 
966 
967  if (timestamp2tm(*tin, NULL, tm, &fsec, NULL) != 0)
968  return -1;
969  tm->tm_mon += span->month;
970  if (tm->tm_mon > MONTHS_PER_YEAR)
971  {
972  tm->tm_year += (tm->tm_mon - 1) / MONTHS_PER_YEAR;
973  tm->tm_mon = (tm->tm_mon - 1) % MONTHS_PER_YEAR + 1;
974  }
975  else if (tm->tm_mon < 1)
976  {
977  tm->tm_year += tm->tm_mon / MONTHS_PER_YEAR - 1;
978  tm->tm_mon = tm->tm_mon % MONTHS_PER_YEAR + MONTHS_PER_YEAR;
979  }
980 
981 
982  /* adjust for end of month boundary problems... */
983  if (tm->tm_mday > day_tab[isleap(tm->tm_year)][tm->tm_mon - 1])
984  tm->tm_mday = (day_tab[isleap(tm->tm_year)][tm->tm_mon - 1]);
985 
986 
987  if (tm2timestamp(tm, fsec, NULL, tin) != 0)
988  return -1;
989  }
990 
991 
992  *tin += span->time;
993  *tout = *tin;
994  }
995  return 0;
996 
997 }
double fsec_t
Definition: timestamp.h:53
#define isleap(y)
Definition: datetime.h:281
int timestamp2tm(Timestamp dt, int *tzp, struct pg_tm *tm, fsec_t *fsec, const char **tzn, pg_tz *attimezone)
Definition: timestamp.c:1951
static struct pg_tm tm
Definition: localtime.c:103
#define MONTHS_PER_YEAR
Definition: timestamp.h:81
#define TIMESTAMP_NOT_FINITE(j)
Definition: timestamp.h:144
int tm_mon
Definition: pgtime.h:31
const int day_tab[2][13]
Definition: datetime.c:65
int tm2timestamp(struct pg_tm *tm, fsec_t fsec, int *tzp, Timestamp *result)
Definition: timestamp.c:2089
#define NULL
Definition: c.h:226
void PGTYPEStimestamp_current ( timestamp ts)

Definition at line 378 of file timestamp.c.

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

Referenced by dtcurrent(), and main().

379 {
380  struct tm tm;
381 
383  if (errno == 0)
384  tm2timestamp(&tm, 0, NULL, ts);
385  return;
386 }
void GetCurrentDateTime(struct pg_tm *tm)
Definition: datetime.c:375
static struct pg_tm tm
Definition: localtime.c:103
int tm2timestamp(struct pg_tm *tm, fsec_t fsec, int *tzp, Timestamp *result)
Definition: timestamp.c:2089
#define NULL
Definition: c.h:226
int PGTYPEStimestamp_defmt_asc ( char *  str,
const char *  fmt,
timestamp d 
)

Definition at line 900 of file timestamp.c.

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

Referenced by dtcvfmtasc(), and main().

901 {
902  int year,
903  month,
904  day;
905  int hour,
906  minute,
907  second;
908  int tz;
909 
910  int i;
911  char *mstr;
912  char *mfmt;
913 
914  if (!fmt)
915  fmt = "%Y-%m-%d %H:%M:%S";
916  if (!fmt[0])
917  return 1;
918 
919  mstr = pgtypes_strdup(str);
920  mfmt = pgtypes_strdup(fmt);
921 
922  /*
923  * initialize with impossible values so that we can see if the fields
924  * where specified at all
925  */
926  /* XXX ambiguity with 1 BC for year? */
927  year = -1;
928  month = -1;
929  day = -1;
930  hour = 0;
931  minute = -1;
932  second = -1;
933  tz = 0;
934 
935  i = PGTYPEStimestamp_defmt_scan(&mstr, mfmt, d, &year, &month, &day, &hour, &minute, &second, &tz);
936  free(mstr);
937  free(mfmt);
938  return i;
939 }
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:2601
#define free(a)
Definition: header.h:60
int i
int PGTYPEStimestamp_fmt_asc ( timestamp ts,
char *  output,
int  str_len,
const char *  fmtstr 
)

Definition at line 872 of file timestamp.c.

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

Referenced by dttofmtasc(), and main().

873 {
874  struct tm tm;
875  fsec_t fsec;
876  date dDate;
877  int dow;
878 
879  dDate = PGTYPESdate_from_timestamp(*ts);
880  dow = PGTYPESdate_dayofweek(dDate);
881  timestamp2tm(*ts, NULL, &tm, &fsec, NULL);
882 
883  return dttofmtasc_replace(ts, dDate, dow, &tm, output, &str_len, fmtstr);
884 }
static int dttofmtasc_replace(timestamp *ts, date dDate, int dow, struct tm *tm, char *output, int *pstr_len, const char *fmtstr)
Definition: timestamp.c:389
double fsec_t
Definition: timestamp.h:53
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:1951
long date
Definition: pgtypes_date.h:8
static struct pg_tm tm
Definition: localtime.c:103
int PGTYPESdate_dayofweek(date)
Definition: datetime.c:144
static void fmtstr(char *value, int leftjust, int minlen, int maxwidth, int pointflag, PrintfTarget *target)
Definition: snprintf.c:804
#define NULL
Definition: c.h:226
date PGTYPESdate_from_timestamp(timestamp)
Definition: datetime.c:32
timestamp PGTYPEStimestamp_from_asc ( char *  str,
char **  endptr 
)

Definition at line 281 of file timestamp.c.

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

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

282 {
283  timestamp result;
284 
285 #ifdef HAVE_INT64_TIMESTAMP
286  int64 noresult = 0;
287 #else
288  double noresult = 0.0;
289 #endif
290  fsec_t fsec;
291  struct tm tt,
292  *tm = &tt;
293  int dtype;
294  int nf;
295  char *field[MAXDATEFIELDS];
296  int ftype[MAXDATEFIELDS];
297  char lowstr[MAXDATELEN + MAXDATEFIELDS];
298  char *realptr;
299  char **ptr = (endptr != NULL) ? endptr : &realptr;
300 
301  if (strlen(str) > MAXDATELEN)
302  {
303  errno = PGTYPES_TS_BAD_TIMESTAMP;
304  return (noresult);
305  }
306 
307  if (ParseDateTime(str, lowstr, field, ftype, &nf, ptr) != 0 ||
308  DecodeDateTime(field, ftype, nf, &dtype, tm, &fsec, 0) != 0)
309  {
310  errno = PGTYPES_TS_BAD_TIMESTAMP;
311  return (noresult);
312  }
313 
314  switch (dtype)
315  {
316  case DTK_DATE:
317  if (tm2timestamp(tm, fsec, NULL, &result) != 0)
318  {
319  errno = PGTYPES_TS_BAD_TIMESTAMP;
320  return (noresult);
321  }
322  break;
323 
324  case DTK_EPOCH:
325  result = SetEpochTimestamp();
326  break;
327 
328  case DTK_LATE:
329  TIMESTAMP_NOEND(result);
330  break;
331 
332  case DTK_EARLY:
333  TIMESTAMP_NOBEGIN(result);
334  break;
335 
336  case DTK_INVALID:
337  errno = PGTYPES_TS_BAD_TIMESTAMP;
338  return (noresult);
339 
340  default:
341  errno = PGTYPES_TS_BAD_TIMESTAMP;
342  return (noresult);
343  }
344 
345  /* AdjustTimestampForTypmod(&result, typmod); */
346 
347  /*
348  * Since it's difficult to test for noresult, make sure errno is 0 if no
349  * error occurred.
350  */
351  errno = 0;
352  return result;
353 }
#define MAXDATELEN
Definition: datetime.h:203
#define TIMESTAMP_NOEND(j)
Definition: timestamp.h:139
double fsec_t
Definition: timestamp.h:53
#define DTK_INVALID
Definition: datetime.h:151
static struct pg_tm tm
Definition: localtime.c:103
int DecodeDateTime(char **field, int *ftype, int nf, int *dtype, struct pg_tm *tm, fsec_t *fsec, int *tzp)
Definition: datetime.c:847
#define TIMESTAMP_NOBEGIN(j)
Definition: timestamp.h:134
#define DTK_LATE
Definition: datetime.h:154
int tm2timestamp(struct pg_tm *tm, fsec_t fsec, int *tzp, Timestamp *result)
Definition: timestamp.c:2089
#define NULL
Definition: c.h:226
#define DTK_EARLY
Definition: datetime.h:153
#define MAXDATEFIELDS
Definition: datetime.h:205
double timestamp
#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:626
#define PGTYPES_TS_BAD_TIMESTAMP
Definition: pgtypes_error.h:15
#define DTK_DATE
Definition: datetime.h:145
Timestamp SetEpochTimestamp(void)
Definition: timestamp.c:2274
int PGTYPEStimestamp_sub ( timestamp ts1,
timestamp ts2,
interval iv 
)

Definition at line 887 of file timestamp.c.

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

Referenced by dtsub().

888 {
889  if (TIMESTAMP_NOT_FINITE(*ts1) || TIMESTAMP_NOT_FINITE(*ts2))
891  else
892  iv->time = (*ts1 - *ts2);
893 
894  iv->month = 0;
895 
896  return 0;
897 }
#define PGTYPES_TS_ERR_EINFTIME
Definition: pgtypes_error.h:16
#define TIMESTAMP_NOT_FINITE(j)
Definition: timestamp.h:144
int PGTYPEStimestamp_sub_interval ( timestamp tin,
interval span,
timestamp tout 
)

Definition at line 1011 of file timestamp.c.

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

1012 {
1013  interval tspan;
1014 
1015  tspan.month = -span->month;
1016  tspan.time = -span->time;
1017 
1018 
1019  return PGTYPEStimestamp_add_interval(tin, &tspan, tout);
1020 }
int PGTYPEStimestamp_add_interval(timestamp *tin, interval *span, timestamp *tout)
Definition: timestamp.c:952
char* PGTYPEStimestamp_to_asc ( timestamp  tstamp)

Definition at line 356 of file timestamp.c.

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

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

357 {
358  struct tm tt,
359  *tm = &tt;
360  char buf[MAXDATELEN + 1];
361  fsec_t fsec;
362  int DateStyle = 1; /* this defaults to ISO_DATES, shall we make
363  * it an option? */
364 
365  if (TIMESTAMP_NOT_FINITE(tstamp))
366  EncodeSpecialTimestamp(tstamp, buf);
367  else if (timestamp2tm(tstamp, NULL, tm, &fsec, NULL) == 0)
368  EncodeDateTime(tm, fsec, false, 0, NULL, DateStyle, buf, 0);
369  else
370  {
371  errno = PGTYPES_TS_BAD_TIMESTAMP;
372  return NULL;
373  }
374  return pgtypes_strdup(buf);
375 }
#define MAXDATELEN
Definition: datetime.h:203
double fsec_t
Definition: timestamp.h:53
int timestamp2tm(Timestamp dt, int *tzp, struct pg_tm *tm, fsec_t *fsec, const char **tzn, pg_tz *attimezone)
Definition: timestamp.c:1951
void EncodeSpecialTimestamp(Timestamp dt, char *str)
Definition: timestamp.c:1641
static struct pg_tm tm
Definition: localtime.c:103
char * pgtypes_strdup(const char *str)
Definition: common.c:19
#define TIMESTAMP_NOT_FINITE(j)
Definition: timestamp.h:144
static char * buf
Definition: pg_test_fsync.c:65
void EncodeDateTime(struct pg_tm *tm, fsec_t fsec, bool print_tz, int tz, const char *tzn, int style, char *str)
Definition: datetime.c:4105
#define NULL
Definition: c.h:226
int DateStyle
Definition: globals.c:106
#define PGTYPES_TS_BAD_TIMESTAMP
Definition: pgtypes_error.h:15
static timestamp SetEpochTimestamp ( void  )
static

Definition at line 94 of file timestamp.c.

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

95 {
96 #ifdef HAVE_INT64_TIMESTAMP
97  int64 noresult = 0;
98 #else
99  double noresult = 0.0;
100 #endif
101  timestamp dt;
102  struct tm tt,
103  *tm = &tt;
104 
105  if (GetEpochTime(tm) < 0)
106  return noresult;
107 
108  tm2timestamp(tm, 0, NULL, &dt);
109  return dt;
110 } /* SetEpochTimestamp() */
static struct pg_tm tm
Definition: localtime.c:103
int tm2timestamp(struct pg_tm *tm, fsec_t fsec, int *tzp, Timestamp *result)
Definition: timestamp.c:2089
#define NULL
Definition: c.h:226
double timestamp
void GetEpochTime(struct pg_tm *tm)
Definition: timestamp.c:2255
static double time2t ( const int  hour,
const int  min,
const int  sec,
const fsec_t  fsec 
)
static

Definition at line 29 of file timestamp.c.

References MINS_PER_HOUR, and SECS_PER_MINUTE.

Referenced by tm2timestamp().

30 {
31  return (((hour * MINS_PER_HOUR) + min) * SECS_PER_MINUTE) + sec + fsec;
32 } /* time2t() */
#define MINS_PER_HOUR
Definition: timestamp.h:101
#define SECS_PER_MINUTE
Definition: timestamp.h:100
static int timestamp2tm ( timestamp  dt,
int *  tzp,
struct tm tm,
fsec_t fsec,
const char **  tzn 
)
static

Definition at line 124 of file timestamp.c.

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

125 {
126 #ifdef HAVE_INT64_TIMESTAMP
127  int64 dDate,
128  date0;
129  int64 time;
130 #else
131  double dDate,
132  date0;
133  double time;
134 #endif
135 #if defined(HAVE_TM_ZONE) || defined(HAVE_INT_TIMEZONE)
136  time_t utime;
137  struct tm *tx;
138 #endif
139 
140  date0 = date2j(2000, 1, 1);
141 
142 #ifdef HAVE_INT64_TIMESTAMP
143  time = dt;
144  TMODULO(time, dDate, USECS_PER_DAY);
145 
146  if (time < INT64CONST(0))
147  {
148  time += USECS_PER_DAY;
149  dDate -= 1;
150  }
151 
152  /* add offset to go from J2000 back to standard Julian date */
153  dDate += date0;
154 
155  /* Julian day routine does not work for negative Julian days */
156  if (dDate < 0 || dDate > (timestamp) INT_MAX)
157  return -1;
158 
159  j2date((int) dDate, &tm->tm_year, &tm->tm_mon, &tm->tm_mday);
160  dt2time(time, &tm->tm_hour, &tm->tm_min, &tm->tm_sec, fsec);
161 #else
162  time = dt;
163  TMODULO(time, dDate, (double) SECS_PER_DAY);
164 
165  if (time < 0)
166  {
167  time += SECS_PER_DAY;
168  dDate -= 1;
169  }
170 
171  /* add offset to go from J2000 back to standard Julian date */
172  dDate += date0;
173 
174 recalc_d:
175  /* Julian day routine does not work for negative Julian days */
176  if (dDate < 0 || dDate > (timestamp) INT_MAX)
177  return -1;
178 
179  j2date((int) dDate, &tm->tm_year, &tm->tm_mon, &tm->tm_mday);
180 recalc_t:
181  dt2time(time, &tm->tm_hour, &tm->tm_min, &tm->tm_sec, fsec);
182 
183  *fsec = TSROUND(*fsec);
184  /* roundoff may need to propagate to higher-order fields */
185  if (*fsec >= 1.0)
186  {
187  time = ceil(time);
188  if (time >= (double) SECS_PER_DAY)
189  {
190  time = 0;
191  dDate += 1;
192  goto recalc_d;
193  }
194  goto recalc_t;
195  }
196 #endif
197 
198  if (tzp != NULL)
199  {
200  /*
201  * Does this fall within the capabilities of the localtime()
202  * interface? Then use this to rotate to the local time zone.
203  */
205  {
206 #if defined(HAVE_TM_ZONE) || defined(HAVE_INT_TIMEZONE)
207 
208 #ifdef HAVE_INT64_TIMESTAMP
209  utime = dt / USECS_PER_SEC +
210  ((date0 - date2j(1970, 1, 1)) * INT64CONST(86400));
211 #else
212  utime = dt + (date0 - date2j(1970, 1, 1)) * SECS_PER_DAY;
213 #endif
214 
215  tx = localtime(&utime);
216  tm->tm_year = tx->tm_year + 1900;
217  tm->tm_mon = tx->tm_mon + 1;
218  tm->tm_mday = tx->tm_mday;
219  tm->tm_hour = tx->tm_hour;
220  tm->tm_min = tx->tm_min;
221  tm->tm_isdst = tx->tm_isdst;
222 
223 #if defined(HAVE_TM_ZONE)
224  tm->tm_gmtoff = tx->tm_gmtoff;
225  tm->tm_zone = tx->tm_zone;
226 
227  *tzp = -tm->tm_gmtoff; /* tm_gmtoff is Sun/DEC-ism */
228  if (tzn != NULL)
229  *tzn = tm->tm_zone;
230 #elif defined(HAVE_INT_TIMEZONE)
232  if (tzn != NULL)
233  *tzn = TZNAME_GLOBAL[(tm->tm_isdst > 0)];
234 #endif
235 #else /* not (HAVE_TM_ZONE || HAVE_INT_TIMEZONE) */
236  *tzp = 0;
237  /* Mark this as *no* time zone available */
238  tm->tm_isdst = -1;
239  if (tzn != NULL)
240  *tzn = NULL;
241 #endif
242  }
243  else
244  {
245  *tzp = 0;
246  /* Mark this as *no* time zone available */
247  tm->tm_isdst = -1;
248  if (tzn != NULL)
249  *tzn = NULL;
250  }
251  }
252  else
253  {
254  tm->tm_isdst = -1;
255  if (tzn != NULL)
256  *tzn = NULL;
257  }
258 
259  tm->tm_yday = dDate - date2j(tm->tm_year, 1, 1) + 1;
260 
261  return 0;
262 } /* timestamp2tm() */
int tm_isdst
Definition: pgtime.h:35
#define USECS_PER_SEC
Definition: timestamp.h:106
int tm_hour
Definition: pgtime.h:29
#define TZNAME_GLOBAL
Definition: port.h:223
#define TIMEZONE_GLOBAL
Definition: port.h:222
long int tm_gmtoff
Definition: pgtime.h:36
static struct pg_tm tm
Definition: localtime.c:103
#define SECS_PER_DAY
Definition: timestamp.h:98
int tm_mday
Definition: pgtime.h:30
#define IS_VALID_UTIME(y, m, d)
Definition: dt.h:324
int tm_mon
Definition: pgtime.h:31
#define USECS_PER_DAY
Definition: timestamp.h:103
const char * tm_zone
Definition: pgtime.h:37
void j2date(int jd, int *year, int *month, int *day)
Definition: datetime.c:322
#define SECS_PER_HOUR
Definition: timestamp.h:99
int date2j(int y, int m, int d)
Definition: datetime.c:297
void dt2time(Timestamp jd, int *hour, int *min, int *sec, fsec_t *fsec)
Definition: timestamp.c:1915
#define NULL
Definition: c.h:226
#define INT64CONST(x)
Definition: c.h:307
double timestamp
#define TSROUND(j)
Definition: timestamp.h:73
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:258
int tm2timestamp ( struct tm tm,
fsec_t  fsec,
int *  tzp,
timestamp result 
)

Definition at line 54 of file timestamp.c.

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

55 {
56 #ifdef HAVE_INT64_TIMESTAMP
57  int dDate;
58  int64 time;
59 #else
60  double dDate,
61  time;
62 #endif
63 
64  /* Prevent overflow in Julian-day routines */
66  return -1;
67 
68  dDate = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - date2j(2000, 1, 1);
69  time = time2t(tm->tm_hour, tm->tm_min, tm->tm_sec, fsec);
70 #ifdef HAVE_INT64_TIMESTAMP
71  *result = (dDate * USECS_PER_DAY) + time;
72  /* check for major overflow */
73  if ((*result - time) / USECS_PER_DAY != dDate)
74  return -1;
75  /* check for just-barely overflow (okay except time-of-day wraps) */
76  /* caution: we want to allow 1999-12-31 24:00:00 */
77  if ((*result < 0 && dDate > 0) ||
78  (*result > 0 && dDate < -1))
79  return -1;
80 #else
81  *result = dDate * SECS_PER_DAY + time;
82 #endif
83  if (tzp != NULL)
84  *result = dt2local(*result, -(*tzp));
85 
86  /* final range check catches just-out-of-range timestamps */
87  if (!IS_VALID_TIMESTAMP(*result))
88  return -1;
89 
90  return 0;
91 } /* tm2timestamp() */
int tm_hour
Definition: pgtime.h:29
static timestamp dt2local(timestamp dt, int tz)
Definition: timestamp.c:36
static struct pg_tm tm
Definition: localtime.c:103
#define SECS_PER_DAY
Definition: timestamp.h:98
int tm_mday
Definition: pgtime.h:30
int tm_mon
Definition: pgtime.h:31
#define IS_VALID_JULIAN(y, m, d)
Definition: timestamp.h:177
#define USECS_PER_DAY
Definition: timestamp.h:103
int date2j(int y, int m, int d)
Definition: datetime.c:297
#define NULL
Definition: c.h:226
#define IS_VALID_TIMESTAMP(t)
Definition: timestamp.h:230
static double time2t(const int hour, const int min, const int sec, const fsec_t fsec)
Definition: timestamp.c:29
int tm_year
Definition: pgtime.h:32
int tm_sec
Definition: pgtime.h:27
int tm_min
Definition: pgtime.h:28