From: "D'Arcy J.M. Cain" <darcy@druid.net>

Subject: [HACKERS] timestamp.c changes

I sent in changes previously and they were rejected because they didn't
follow ANSI spec.  Here is the input part of the changes again.  Even
though it allows more flexibility for inputting different formats, it
is also backwards compatible with the standard version.  I have also
not changed the output format so it will still output the ANSI forms.
Is this acceptable to everyone?
This commit is contained in:
Marc G. Fournier 1997-04-03 19:58:11 +00:00
parent 9d5c0af586
commit 4bc578eb83
1 changed files with 88 additions and 8 deletions

View File

@ -1,27 +1,107 @@
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <ctype.h>
#include "postgres.h"
#include "utils/builtins.h"
/* copy the next part of the string into a buffer */
static const char *
cpstr(const char *s, char *buf)
{
char in = 0;
while (isspace(*s))
s++;
for (; *s && !isspace(*s); s++)
{
if (strchr("-,:/", *s))
{
buf[in] = 0;
return(s + 1);
}
if (in < 16)
buf[in++] = tolower(*s);
}
buf[in] = 0;
return s;
}
/* assumes dd/mm/yyyy unless first item is month in word form */
time_t
timestamp_in(const char *timestamp_str)
{
struct tm input_time;
int4 result;
char buf[18];
const char *p;
static const char *mstr[] = {
"january", "february", "march", "april", "may", "june",
"july", "august", "september", "october", "november", "december"
};
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",
p = cpstr(timestamp_str, buf);
if (isdigit(buf[0])) /* must be dd/mm/yyyy */
{
input_time.tm_mday = atoi(buf);
p = cpstr(p, buf);
if (!buf[0])
elog(WARN, "timestamp_in: timestamp \"%s\" not a proper date",
timestamp_str);
if (isdigit(buf[0]))
{
input_time.tm_mon = atoi(buf) - 1;
if (input_time.tm_mon < 0 || input_time.tm_mon > 11)
elog(WARN, "timestamp_in: timestamp \"%s\" invalid month",
timestamp_str);
}
else
{
int i;
for (i = 0; i < 12; i++)
if (strncmp(mstr[i], buf, strlen(buf)) == 0)
break;
if (1 > 11)
elog(WARN, "timestamp_in: timestamp \"%s\" invalid month",
timestamp_str);
input_time.tm_mon = i;
}
}
else /* must be month/dd/yyyy */
{
int i;
for (i = 0; i < 12; i++)
if (strncmp(mstr[i], buf, strlen(buf)) == 0)
break;
if (1 > 11)
elog(WARN, "timestamp_in: timestamp \"%s\" invalid month",
timestamp_str);
input_time.tm_mon = i;
p = cpstr(p, buf);
input_time.tm_mday = atoi(buf);
if (!input_time.tm_mday || input_time.tm_mday > 31)
elog(WARN, "timestamp_in: timestamp \"%s\" not a proper date",
timestamp_str);
}
/* range checking? bahahahaha.... */
p = cpstr(p, buf);
if (!buf[0] || !isdigit(buf[0]))
elog(WARN, "timestamp_in: timestamp \"%s\" not a proper date",
timestamp_str);
if ((input_time.tm_year = atoi(buf)) < 1900)
input_time.tm_year += 1900;
input_time.tm_year -= 1900;
input_time.tm_mon -= 1;
/* now get the time */
p = cpstr(p, buf);
input_time.tm_hour = atoi(buf);
p = cpstr(p, buf);
input_time.tm_min = atoi(buf);
p = cpstr(p, buf);
input_time.tm_sec = atoi(buf);
/* use mktime(), but make this GMT, not local time */
result = mktime(&input_time);
@ -35,7 +115,7 @@ timestamp_out(time_t timestamp)
char *result;
struct tm *time;
time = localtime((time_t *)&timestamp);
time = localtime(&timestamp);
result = palloc(20);
sprintf(result, "%04d-%02d-%02d %02d:%02d:%02d",
time->tm_year+1900, time->tm_mon+1, time->tm_mday,