summaryrefslogtreecommitdiff
path: root/contrib/datetime/datetime_functions.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/datetime/datetime_functions.c')
-rw-r--r--contrib/datetime/datetime_functions.c207
1 files changed, 151 insertions, 56 deletions
diff --git a/contrib/datetime/datetime_functions.c b/contrib/datetime/datetime_functions.c
index d2c097583cf..e925d985bfb 100644
--- a/contrib/datetime/datetime_functions.c
+++ b/contrib/datetime/datetime_functions.c
@@ -6,113 +6,208 @@
* Copyright (c) 1996, Massimo Dal Zotto <dz@cs.unitn.it>
*/
-#include <time.h>
+#include <stdio.h> /* for sprintf() */
+#include <string.h>
+#include <limits.h>
+#ifdef HAVE_FLOAT_H
+#include <float.h>
+#endif
#include "postgres.h"
-#include "utils/palloc.h"
+#include "miscadmin.h"
+#include "utils/builtins.h"
+#include "utils/nabstime.h"
#include "utils/datetime.h"
+#include "access/xact.h"
+#include "datetime_functions.h"
-TimeADT *
-time_difference(TimeADT *time1, TimeADT *time2)
+/* Constant to replace calls to date2j(2000,1,1) */
+#define JDATE_2000 2451545
+
+/*
+ * A modified version of time_in which allows the value 24:00:00 for
+ * time and converts it to TimeADT data type forcing seconds to 0.
+ * This can be Useful if you need to handle TimeADT values limited
+ * to hh:mm like in timetables.
+ */
+
+TimeADT *
+hhmm_in(char *str)
+{
+ TimeADT *time;
+
+ double fsec;
+ struct tm tt, *tm = &tt;
+
+ int nf;
+ char lowstr[MAXDATELEN+1];
+ char *field[MAXDATEFIELDS];
+ int dtype;
+ int ftype[MAXDATEFIELDS];
+
+ if (!PointerIsValid(str))
+ elog(WARN,"Bad (null) time external representation",NULL);
+
+ if ((ParseDateTime( str, lowstr, field, ftype, MAXDATEFIELDS, &nf) != 0)
+ || (DecodeTimeOnly( field, ftype, nf, &dtype, tm, &fsec) != 0))
+ elog(WARN,"Bad time external representation '%s'",str);
+
+ if (tm->tm_hour<0 || tm->tm_hour>24 ||
+ (tm->tm_hour==24 && (tm->tm_min!=0 || tm->tm_sec!=0 || fsec!= 0))) {
+ elog(WARN,
+ "time_in: hour must be limited to values 0 through 24:00 "
+ "in \"%s\"",
+ str);
+ }
+ if ((tm->tm_min < 0) || (tm->tm_min > 59))
+ elog(WARN,"Minute must be limited to values 0 through 59 in '%s'",str);
+ if ((tm->tm_sec < 0) || ((tm->tm_sec + fsec) >= 60))
+ elog(WARN,"Second must be limited to values 0 through < 60 in '%s'",
+ str);
+
+ time = PALLOCTYPE(TimeADT);
+
+ *time = ((((tm->tm_hour*60)+tm->tm_min)*60));
+
+ return(time);
+}
+
+/*
+ * A modified version of time_out which converts from TimeADT data type
+ * omitting the seconds field when it is 0.
+ * Useful if you need to handle TimeADT values limited to hh:mm.
+ */
+
+char *
+hhmm_out(TimeADT *time)
{
- TimeADT *result = (TimeADT *) palloc(sizeof(TimeADT));
+ char *result;
+ struct tm tt, *tm = &tt;
+ char buf[MAXDATELEN+1];
+
+ if (!PointerIsValid(time))
+ return NULL;
+
+ tm->tm_hour = (*time / (60*60));
+ tm->tm_min = (((int) (*time / 60)) % 60);
+ tm->tm_sec = (((int) *time) % 60);
+
+ if (tm->tm_sec == 0) {
+ sprintf(buf, "%02d:%02d", tm->tm_hour, tm->tm_min);
+ } else {
+ sprintf(buf, "%02d:%02d:%02d", tm->tm_hour, tm->tm_min, tm->tm_sec);
+ }
- *result = *time1 - *time2;
- return (result);
+ result = PALLOC(strlen(buf)+1);
+
+ strcpy( result, buf);
+
+ return(result);
}
-TimeADT *
-currenttime()
+TimeADT *
+hhmm(TimeADT *time)
{
- time_t current_time;
- struct tm *tm;
- TimeADT *result = (TimeADT *) palloc(sizeof(TimeADT));
-
- current_time = time(NULL);
- tm = localtime(&current_time);
- *result = ((((tm->tm_hour * 60) + tm->tm_min) * 60) + tm->tm_sec);
- return (result);
+ TimeADT *result = PALLOCTYPE(TimeADT);
+
+ *result = (((int) *time) / 60 * 60);
+
+ return(result);
}
-DateADT
-currentdate()
+TimeADT *
+time_difference(TimeADT *time1, TimeADT *time2)
{
- time_t current_time;
- struct tm *tm;
- DateADT result;
+ TimeADT *time = PALLOCTYPE(TimeADT);
- current_time = time(NULL);
- tm = localtime(&current_time);
+ *time = (*time1 - *time2);
+ return(time);
+}
+
+int4
+time_hours(TimeADT *time)
+{
+ return (((int) *time) / 3600);
+}
- result = date2j(tm->tm_year, tm->tm_mon + 1, tm->tm_mday) -
- date2j(100, 1, 1);
- return (result);
+int4
+time_minutes(TimeADT *time)
+{
+ return ((((int) *time) / 60) % 60);
}
int4
-hours(TimeADT *time)
+time_seconds(TimeADT *time)
{
- return (*time / (60 * 60));
+ return (((int) *time) % 60);
}
int4
-minutes(TimeADT *time)
+as_minutes(TimeADT *time)
{
- return (((int) (*time / 60)) % 60);
+ return (((int) *time) / 60);
}
int4
-seconds(TimeADT *time)
+as_seconds(TimeADT *time)
{
- return (((int) *time) % 60);
+ return ((int) *time);
}
int4
-day(DateADT *date)
+date_day(DateADT val)
{
- struct tm tm;
+ int year, month, day;
- j2date((*date + date2j(2000, 1, 1)),
- &tm.tm_year, &tm.tm_mon, &tm.tm_mday);
+ j2date(val + JDATE_2000, &year, &month, &day);
- return (tm.tm_mday);
+ return (day);
}
int4
-month(DateADT *date)
+date_month(DateADT val)
{
- struct tm tm;
+ int year, month, day;
- j2date((*date + date2j(2000, 1, 1)),
- &tm.tm_year, &tm.tm_mon, &tm.tm_mday);
+ j2date(val + JDATE_2000, &year, &month, &day);
- return (tm.tm_mon);
+ return (month);
}
int4
-year(DateADT *date)
+date_year(DateADT val)
{
- struct tm tm;
+ int year, month, day;
- j2date((*date + date2j(2000, 1, 1)),
- &tm.tm_year, &tm.tm_mon, &tm.tm_mday);
+ j2date(val + JDATE_2000, &year, &month, &day);
- return (tm.tm_year);
+ return (year);
}
-int4
-asminutes(TimeADT *time)
+TimeADT *
+currenttime()
{
- int seconds = (int) *time;
+ TimeADT *result = PALLOCTYPE(TimeADT);
+ struct tm *tm;
+ time_t current_time;
+
+ current_time = time(NULL);
+ tm = localtime(&current_time);
+ *result = ((((tm->tm_hour*60)+tm->tm_min)*60)+tm->tm_sec);
- return (seconds / 60);
+ return (result);
}
-int4
-asseconds(TimeADT *time)
+DateADT
+currentdate()
{
- int seconds = (int) *time;
+ DateADT date;
+ struct tm tt, *tm = &tt;
- return (seconds);
+ GetCurrentTime(tm);
+ date = (date2j( tm->tm_year, tm->tm_mon, tm->tm_mday) - JDATE_2000);
+ return (date);
}
+
+/* end of file */