/* * datetime_functions.c -- * * This file defines new functions for the time and date data types. * * Copyright (c) 1996, Massimo Dal Zotto */ #include /* for sprintf() */ #include #include #ifdef HAVE_FLOAT_H #include #endif #include "postgres.h" #include "miscadmin.h" #include "utils/builtins.h" #include "utils/nabstime.h" #include "utils/datetime.h" #include "access/xact.h" #include "datetime_functions.h" /* 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) { 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 = PALLOC(strlen(buf)+1); strcpy( result, buf); return(result); } TimeADT * hhmm(TimeADT *time) { TimeADT *result = PALLOCTYPE(TimeADT); *result = (((int) *time) / 60 * 60); return(result); } TimeADT * time_difference(TimeADT *time1, TimeADT *time2) { TimeADT *time = PALLOCTYPE(TimeADT); *time = (*time1 - *time2); return(time); } int4 time_hours(TimeADT *time) { return (((int) *time) / 3600); } int4 time_minutes(TimeADT *time) { return ((((int) *time) / 60) % 60); } int4 time_seconds(TimeADT *time) { return (((int) *time) % 60); } int4 as_minutes(TimeADT *time) { return (((int) *time) / 60); } int4 as_seconds(TimeADT *time) { return ((int) *time); } int4 date_day(DateADT val) { int year, month, day; j2date(val + JDATE_2000, &year, &month, &day); return (day); } int4 date_month(DateADT val) { int year, month, day; j2date(val + JDATE_2000, &year, &month, &day); return (month); } int4 date_year(DateADT val) { int year, month, day; j2date(val + JDATE_2000, &year, &month, &day); return (year); } TimeADT * currenttime() { TimeADT *result = PALLOCTYPE(TimeADT); struct tm *tm; time_t current_time; current_time = time(NULL); tm = localtime(¤t_time); *result = ((((tm->tm_hour*60)+tm->tm_min)*60)+tm->tm_sec); return (result); } DateADT currentdate() { DateADT date; struct tm tt, *tm = &tt; GetCurrentTime(tm); date = (date2j( tm->tm_year, tm->tm_mon, tm->tm_mday) - JDATE_2000); return (date); } /* end of file */