aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/datetimes.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/adt/datetimes.c')
-rw-r--r--src/backend/utils/adt/datetimes.c350
1 files changed, 350 insertions, 0 deletions
diff --git a/src/backend/utils/adt/datetimes.c b/src/backend/utils/adt/datetimes.c
new file mode 100644
index 00000000000..b6207be263c
--- /dev/null
+++ b/src/backend/utils/adt/datetimes.c
@@ -0,0 +1,350 @@
+/*-------------------------------------------------------------------------
+ *
+ * datetimes.c--
+ * implements DATE and TIME data types specified in SQL-92 standard
+ *
+ * Copyright (c) 1994-5, Regents of the University of California
+ *
+ *
+ * IDENTIFICATION
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/datetimes.c,v 1.1.1.1 1996/07/09 06:22:03 scrappy Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+#include <stdio.h> /* for sprintf() */
+#include <string.h>
+#include "postgres.h"
+#include "utils/palloc.h"
+#include "utils/elog.h"
+
+/* these things look like structs, but we pass them by value so be careful
+ For example, passing an int -> DateADT is not portable! */
+typedef struct DateADT {
+ char day;
+ char month;
+ short year;
+} DateADT;
+
+typedef struct TimeADT {
+ short hr;
+ short min;
+ float sec;
+} TimeADT;
+
+#ifndef EUROPEAN_STYLE
+#define AMERICAN_STYLE
+#endif
+
+static int day_tab[2][12] = {
+ {31,28,31,30,31,30,31,31,30,31,30,31},
+ {31,29,31,30,31,30,31,31,30,31,30,31} };
+
+static int
+isleap(int year)
+{
+ return
+ (((year % 4) == 0 && (year % 100) != 0) || (year % 400) == 0);
+}
+
+/*****************************************************************************
+ * Date ADT
+ *****************************************************************************/
+
+int4
+date_in(char *datestr)
+{
+ int d, m, y;
+ int4 result;
+ DateADT *date = (DateADT*)&result;
+
+#ifdef USE_SHORT_YEAR
+#define CHECK_DATE_LEN(datestr) (strlen(datestr) >= 8)
+#else
+#define CHECK_DATE_LEN(datestr) (strlen(datestr) == 10)
+#endif /* USE_SHORT_YEAR */
+
+#ifdef AMERICAN_STYLE
+ if (!CHECK_DATE_LEN(datestr) ||
+ sscanf(datestr, "%d%*c%d%*c%d", &m, &d, &y) != 3) {
+ elog(WARN, "date_in: date \"%s\" not of the form mm-dd-yyyy",
+ datestr);
+ }
+#else
+ if (!CHECK_DATE_LEN(datestr) ||
+ sscanf(datestr, "%d%*c%d%*c%d", &d, &m, &y) != 3) {
+ elog(WARN, "date_in: date \"%s\" not of the form dd-mm-yyyy",
+ datestr);
+ }
+#endif
+ if (m < 1 || m > 12)
+ elog(WARN, "date_in: month must be limited to values 1 through 12 in \"%s\"", datestr);
+ if (d < 1 || d > day_tab[isleap(y)][m-1])
+ elog(WARN, "date_in: day must be limited to values 1 through %d in \"%s\"",
+ day_tab[isleap(y)][m-1], datestr);
+
+#ifdef USE_SHORT_YEAR
+ if (y < 100)
+ y += 1900; /* hack! */
+#endif /* USE_SHORT_YEAR */
+
+ date->day = d;
+ date->month = m;
+ date->year = y;
+ return result;
+}
+
+char *
+date_out(int4 dateVal)
+{
+ char *datestr = palloc(11);
+ int4 dateStore;
+ DateADT *date;
+
+ /* DateADT is a structure that happens to be four bytes long,
+ trust me on this.... */
+ date = (DateADT*)&dateStore;
+ dateStore = dateVal;
+
+#ifdef AMERICAN_STYLE
+ sprintf(datestr, "%02d-%02d-%04d",
+ (int)date->month, (int)date->day, (int)date->year);
+#else
+ sprintf(datestr, "%02d-%02d-%04d",
+ (int)date->day, (int)date->month, (int)date->year);
+#endif
+
+ return datestr;
+}
+
+
+int
+date_eq(int4 dateVal1, int4 dateVal2)
+{
+ int4 dateStore1 = dateVal1;
+ int4 dateStore2 = dateVal2;
+ DateADT *date1, *date2;
+
+ date1 = (DateADT*)&dateStore1;
+ date2 = (DateADT*)&dateStore2;
+
+ return (date1->day==date2->day &&
+ date1->month==date2->month &&
+ date1->year==date2->year);
+}
+
+int
+date_ne(int4 dateVal1, int4 dateVal2)
+{
+ int4 dateStore1 = dateVal1;
+ int4 dateStore2 = dateVal2;
+ DateADT *date1, *date2;
+
+ date1 = (DateADT*)&dateStore1;
+ date2 = (DateADT*)&dateStore2;
+
+ return (date1->day!=date2->day || date1->month!=date2->month ||
+ date1->year!=date2->year);
+}
+
+int
+date_lt(int4 dateVal1, int4 dateVal2)
+{
+ int4 dateStore1 = dateVal1;
+ int4 dateStore2 = dateVal2;
+ DateADT *date1, *date2;
+
+ date1 = (DateADT*)&dateStore1;
+ date2 = (DateADT*)&dateStore2;
+
+ if (date1->year!=date2->year)
+ return (date1->year<date2->year);
+ if (date1->month!=date2->month)
+ return (date1->month<date2->month);
+ return (date1->day<date2->day);
+}
+
+int
+date_le(int4 dateVal1, int4 dateVal2)
+{
+
+ int4 dateStore1 = dateVal1;
+ int4 dateStore2 = dateVal2;
+ DateADT *date1, *date2;
+
+ date1 = (DateADT*)&dateStore1;
+ date2 = (DateADT*)&dateStore2;
+
+ if (date1->year!=date2->year)
+ return (date1->year<=date2->year);
+ if (date1->month!=date2->month)
+ return (date1->month<=date2->month);
+ return (date1->day<=date2->day);
+}
+
+int
+date_gt(int4 dateVal1, int4 dateVal2)
+{
+ int4 dateStore1 = dateVal1;
+ int4 dateStore2 = dateVal2;
+ DateADT *date1, *date2;
+
+ date1 = (DateADT*)&dateStore1;
+ date2 = (DateADT*)&dateStore2;
+
+
+ if (date1->year!=date2->year)
+ return (date1->year>date2->year);
+ if (date1->month!=date2->month)
+ return (date1->month>date2->month);
+ return (date1->day>date2->day);
+}
+
+int
+date_ge(int4 dateVal1, int4 dateVal2)
+{
+ int4 dateStore1 = dateVal1;
+ int4 dateStore2 = dateVal2;
+ DateADT *date1, *date2;
+
+ date1 = (DateADT*)&dateStore1;
+ date2 = (DateADT*)&dateStore2;
+
+ if (date1->year!=date2->year)
+ return (date1->year>=date2->year);
+ if (date1->month!=date2->month)
+ return (date1->month>=date2->month);
+ return (date1->day>=date2->day);
+}
+
+int
+date_cmp(int4 dateVal1, int4 dateVal2)
+{
+ int4 dateStore1 = dateVal1;
+ int4 dateStore2 = dateVal2;
+ DateADT *date1, *date2;
+
+ date1 = (DateADT*)&dateStore1;
+ date2 = (DateADT*)&dateStore2;
+
+ if (date1->year!=date2->year)
+ return ((date1->year<date2->year) ? -1 : 1);
+ if (date1->month!=date2->month)
+ return ((date1->month<date2->month) ? -1 : 1);
+ if (date1->day!=date2->day)
+ return ((date1->day<date2->day) ? -1 : 1);
+ return 0;
+}
+
+/*****************************************************************************
+ * Time ADT
+ *****************************************************************************/
+
+char *
+time_in(char *timestr)
+{
+ int h, m;
+ float sec;
+ TimeADT *time;
+
+ if (sscanf(timestr, "%d%*c%d%*c%f", &h, &m, &sec) != 3) {
+ elog(WARN, "time_in: time \"%s\" not of the form hh:mm:ss",
+ timestr);
+ }
+
+ if (h < 0 || h > 23)
+ elog(WARN, "time_in: hour must be limited to values 0 through 23 in \"%s\"", timestr);
+ if (m < 0 || m > 59)
+ elog(WARN, "time_in: minute must be limited to values 0 through 59 in \"%s\"", timestr);
+ if (sec < 0 || sec >= 62.0)
+ elog(WARN, "time_in: second must be limited to values 0 through 61.99 in \"%s\"", timestr);
+
+ time = (TimeADT*)palloc(sizeof(TimeADT));
+ time->hr = h;
+ time->min = m;
+ time->sec = sec;
+ return (char*)time;
+}
+
+char *
+time_out(TimeADT *time)
+{
+ char *timestr = palloc(16);
+
+ sprintf(timestr, "%02d:%02d:%09.6f",
+ (int)time->hr, (int)time->min, time->sec);
+
+ return timestr;
+}
+
+
+int
+time_eq(TimeADT *time1, TimeADT *time2)
+{
+ return (time1->sec==time2->sec && time1->min==time2->min &&
+ time1->hr==time2->hr);
+}
+
+int
+time_ne(TimeADT *time1, TimeADT *time2)
+{
+ return (time1->sec!=time2->sec || time1->min!=time2->min ||
+ time1->hr!=time2->hr);
+}
+
+int
+time_lt(TimeADT *time1, TimeADT *time2)
+{
+ if (time1->hr!=time2->hr)
+ return (time1->hr<time2->hr);
+ if (time1->min!=time2->min)
+ return (time1->min<time2->min);
+ return (time1->sec<time2->sec);
+}
+
+int
+time_le(TimeADT *time1, TimeADT *time2)
+{
+ if (time1->hr!=time2->hr)
+ return (time1->hr<=time2->hr);
+ if (time1->min!=time2->min)
+ return (time1->min<=time2->min);
+ return (time1->sec<=time2->sec);
+}
+
+int
+time_gt(TimeADT *time1, TimeADT *time2)
+{
+ if (time1->hr!=time2->hr)
+ return (time1->hr>time2->hr);
+ if (time1->min!=time2->min)
+ return (time1->min>time2->min);
+ return (time1->sec>time2->sec);
+}
+
+int
+time_ge(TimeADT *time1, TimeADT *time2)
+{
+ if (time1->hr!=time2->hr)
+ return (time1->hr>=time2->hr);
+ if (time1->min!=time2->min)
+ return (time1->min>=time2->min);
+ return (time1->sec>=time2->sec);
+}
+
+int
+time_cmp(TimeADT *time1, TimeADT *time2)
+{
+ if (time1->hr!=time2->hr)
+ return ((time1->hr<time2->hr) ? -1 : 1);
+ if (time1->min!=time2->min)
+ return ((time1->min<time2->min) ? -1 : 1);
+ if (time1->sec!=time2->sec)
+ return ((time1->sec<time2->sec) ? -1 : 1);
+ return 0;
+}
+
+int32 /* RelativeTime */
+int42reltime(int32 timevalue)
+{
+ return(timevalue);
+}