postgres/src/backend/utils/adt/timestamp.c
Marc G. Fournier 070381482f From: "D'Arcy J.M. Cain" <darcy@druid.net>
Subject: [HACKERS] backend/utils/adt/timestamp.c

Back to this timezone stuff.  The struct tm has a field (tm_gmtoff) which
is the offset from UTC (GMT is archaic BTW) in seconds.  Is this the
value you are looking for when you use timezone?  Note that this applies
to NetBSD but it does not appear to be in either ANSI C or POSIX.  This
looks like one of those things that is just going to have to be hand
coded for each platform.

Why not just store the values in UTC and use localtime instead of
gmtime when retrieving the value?

Also, you assume the time is returned as a 4 byte integer.  In fact,
there is not even any requirement that time be an integral value.  You
should use time_t here.

The input function seems unduly restrictive.  Somewhere in the sources
there is an input function that allows words for months.  Can't we do
the same here?

There is a standard function, difftime, for subtracting two times.  It
deals with cases where time_t is not integral.  There is, however, a
small performance hit since it returns a double and I don't believe
there is any system currently which uses anything but an integral for
time_t.  Still, this is technically the correct and portable thing to do.

The returns from the various comparisons should probably be a bool.
1997-03-25 09:25:33 +00:00

91 lines
1.6 KiB
C

#include <stdio.h>
#include <string.h>
#include <time.h>
#include "postgres.h"
#include "utils/builtins.h"
time_t
timestamp_in(const char *timestamp_str)
{
struct tm input_time;
int4 result;
memset(&input_time, 0, sizeof(input_time));
if(sscanf(timestamp_str, "%d%*c%d%*c%d%*c%d%*c%d%*c%d",
&input_time.tm_year, &input_time.tm_mon, &input_time.tm_mday,
&input_time.tm_hour, &input_time.tm_min, &input_time.tm_sec) != 6) {
elog(WARN, "timestamp_in: timestamp \"%s\" not of the form yyyy-mm-dd hh:mm:ss",
timestamp_str);
}
/* range checking? bahahahaha.... */
input_time.tm_year -= 1900;
input_time.tm_mon -= 1;
/* use mktime(), but make this GMT, not local time */
result = mktime(&input_time);
return result;
}
char *
timestamp_out(time_t timestamp)
{
char *result;
struct tm *time;
time = localtime((time_t *)&timestamp);
result = palloc(20);
sprintf(result, "%04d-%02d-%02d %02d:%02d:%02d",
time->tm_year+1900, time->tm_mon+1, time->tm_mday,
time->tm_hour, time->tm_min, time->tm_sec);
return result;
}
time_t
now(void)
{
time_t sec;
time(&sec);
return(sec);
}
bool
timestampeq(time_t t1, time_t t2)
{
return difftime(t1, t2) == 0;
}
bool
timestampne(time_t t1, time_t t2)
{
return difftime(t1, t2) != 0;
}
bool
timestamplt(time_t t1, time_t t2)
{
return difftime(t1, t2) > 0;
}
bool
timestampgt(time_t t1, time_t t2)
{
return difftime(t1, t2) < 0;
}
bool
timestample(time_t t1, time_t t2)
{
return difftime(t1, t2) >= 0;
}
bool
timestampge(time_t t1, time_t t2)
{
return difftime(t1, t2) <= 0;
}