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:
parent
9d5c0af586
commit
4bc578eb83
@ -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 *)×tamp);
|
||||
time = localtime(×tamp);
|
||||
result = palloc(20);
|
||||
sprintf(result, "%04d-%02d-%02d %02d:%02d:%02d",
|
||||
time->tm_year+1900, time->tm_mon+1, time->tm_mday,
|
||||
|
Loading…
Reference in New Issue
Block a user