Use common parser and encoder for timestamp data type.
Remove older date and time code (retain NEW_DATE_CODE and NEW_TIME_CODE). Use common encoder for date and time. Fix datetime +/- timespan math bug.
This commit is contained in:
parent
43deb7a45f
commit
8507ddb9c6
@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/datetime.c,v 1.9 1997/06/23 14:47:26 thomas Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/datetime.c,v 1.10 1997/07/01 00:22:40 thomas Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -114,15 +114,24 @@ char *
|
||||
date_out(DateADT date)
|
||||
{
|
||||
char *result;
|
||||
struct tm tt, *tm = &tt;
|
||||
char buf[MAXDATELEN+1];
|
||||
|
||||
#if FALSE
|
||||
int year, month, day;
|
||||
#endif
|
||||
|
||||
j2date( (date + date2j(2000,1,1)), &year, &month, &day);
|
||||
j2date( (date + date2j(2000,1,1)),
|
||||
&(tm->tm_year), &(tm->tm_mon), &(tm->tm_mday));
|
||||
|
||||
EncodeDateOnly( tm, DateStyle, buf);
|
||||
|
||||
#if FALSE
|
||||
if (EuroDates == 1) /* Output European-format dates */
|
||||
sprintf(buf, "%02d-%02d-%04d", day, month, year);
|
||||
else
|
||||
sprintf(buf, "%02d-%02d-%04d", month, day, year);
|
||||
#endif
|
||||
|
||||
result = PALLOC(strlen(buf)+1);
|
||||
|
||||
@ -445,19 +454,25 @@ char *
|
||||
time_out(TimeADT *time)
|
||||
{
|
||||
char *result;
|
||||
struct tm tt, *tm = &tt;
|
||||
#if FALSE
|
||||
int hour, min, sec;
|
||||
#endif
|
||||
double fsec;
|
||||
char buf[32];
|
||||
char buf[MAXDATELEN+1];
|
||||
|
||||
if (!PointerIsValid(time))
|
||||
return NULL;
|
||||
|
||||
hour = (*time / (60*60));
|
||||
min = (((int) (*time / 60)) % 60);
|
||||
sec = (((int) *time) % 60);
|
||||
tm->tm_hour = (*time / (60*60));
|
||||
tm->tm_min = (((int) (*time / 60)) % 60);
|
||||
tm->tm_sec = (((int) *time) % 60);
|
||||
|
||||
fsec = 0;
|
||||
|
||||
EncodeTimeOnly( tm, fsec, DateStyle, buf);
|
||||
|
||||
#if FALSE
|
||||
if (sec == 0.0) {
|
||||
sprintf(buf, "%02d:%02d", hour, min);
|
||||
|
||||
@ -468,6 +483,7 @@ time_out(TimeADT *time)
|
||||
sprintf(buf, "%02d:%02d:%05.2f", hour, min, (sec+fsec));
|
||||
};
|
||||
};
|
||||
#endif
|
||||
|
||||
result = PALLOC(strlen(buf)+1);
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/dt.c,v 1.26 1997/06/23 14:50:56 thomas Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/dt.c,v 1.27 1997/07/01 00:22:43 thomas Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -722,6 +722,7 @@ printf( "datetime_add_span- date was %04d-%02d-%02d %02d:%02d:%02d\n",
|
||||
tm->tm_mday = mdays[ tm->tm_mon-1];
|
||||
};
|
||||
};
|
||||
|
||||
#ifdef DATEDEBUG
|
||||
printf( "datetime_add_span- date becomes %04d-%02d-%02d %02d:%02d:%02d\n",
|
||||
tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
@ -897,6 +898,125 @@ timespan_sub(TimeSpan *span1, TimeSpan *span2)
|
||||
} /* timespan_sub() */
|
||||
|
||||
|
||||
/* datetime_age()
|
||||
* Calculate time difference while retaining year/month fields.
|
||||
* Note that this does not result in an accurate absolute time span
|
||||
* since year and month are out of context once the arithmetic
|
||||
* is done.
|
||||
*/
|
||||
TimeSpan *
|
||||
datetime_age(DateTime *datetime1, DateTime *datetime2)
|
||||
{
|
||||
TimeSpan *result;
|
||||
|
||||
DateTime dt1, dt2;
|
||||
double fsec, fsec1, fsec2;
|
||||
struct tm tt, *tm = &tt;
|
||||
struct tm tt1, *tm1 = &tt1;
|
||||
struct tm tt2, *tm2 = &tt2;
|
||||
|
||||
if (!PointerIsValid(datetime1) || !PointerIsValid(datetime2))
|
||||
return NULL;
|
||||
|
||||
result = PALLOCTYPE(TimeSpan);
|
||||
|
||||
dt1 = *datetime1;
|
||||
dt2 = *datetime2;
|
||||
|
||||
if (DATETIME_IS_RELATIVE(dt1)) dt1 = SetDateTime(dt1);
|
||||
if (DATETIME_IS_RELATIVE(dt2)) dt2 = SetDateTime(dt2);
|
||||
|
||||
if (DATETIME_IS_INVALID(dt1)
|
||||
|| DATETIME_IS_INVALID(dt2)) {
|
||||
DATETIME_INVALID( result->time);
|
||||
|
||||
} else if ((datetime2tm( dt1, NULL, tm1, &fsec1, NULL) == 0)
|
||||
&&(datetime2tm( dt2, NULL, tm2, &fsec2, NULL) == 0)) {
|
||||
fsec = (fsec1 - fsec2);
|
||||
tm->tm_sec = (tm1->tm_sec - tm2->tm_sec);
|
||||
tm->tm_min = (tm1->tm_min - tm2->tm_min);
|
||||
tm->tm_hour = (tm1->tm_hour - tm2->tm_hour);
|
||||
tm->tm_mday = (tm1->tm_mday - tm2->tm_mday);
|
||||
tm->tm_mon = (tm1->tm_mon - tm2->tm_mon);
|
||||
tm->tm_year = (tm1->tm_year - tm2->tm_year);
|
||||
|
||||
/* flip sign if necessary... */
|
||||
if (dt1 < dt2) {
|
||||
fsec = -fsec;
|
||||
tm->tm_sec = -tm->tm_sec;
|
||||
tm->tm_min = -tm->tm_min;
|
||||
tm->tm_hour = -tm->tm_hour;
|
||||
tm->tm_mday = -tm->tm_mday;
|
||||
tm->tm_mon = -tm->tm_mon;
|
||||
tm->tm_year = -tm->tm_year;
|
||||
};
|
||||
|
||||
if (tm->tm_sec < 0) {
|
||||
tm->tm_sec += 60;
|
||||
tm->tm_min--;
|
||||
};
|
||||
|
||||
if (tm->tm_min < 0) {
|
||||
tm->tm_min += 60;
|
||||
tm->tm_hour--;
|
||||
};
|
||||
|
||||
if (tm->tm_hour < 0) {
|
||||
tm->tm_hour += 24;
|
||||
tm->tm_mday--;
|
||||
};
|
||||
|
||||
if (tm->tm_mday < 0) {
|
||||
if (dt1 < dt2) {
|
||||
tm->tm_mday += mdays[tm1->tm_mon-1];
|
||||
if (isleap(tm1->tm_year) && (tm1->tm_mon == 2)) tm->tm_mday++;
|
||||
tm->tm_mon--;
|
||||
} else {
|
||||
tm->tm_mday += mdays[tm2->tm_mon-1];
|
||||
if (isleap(tm2->tm_year) && (tm2->tm_mon == 2)) tm->tm_mday++;
|
||||
tm->tm_mon--;
|
||||
};
|
||||
};
|
||||
|
||||
if (tm->tm_mon < 0) {
|
||||
tm->tm_mon += 12;
|
||||
tm->tm_year--;
|
||||
};
|
||||
|
||||
/* recover sign if necessary... */
|
||||
if (dt1 < dt2) {
|
||||
fsec = -fsec;
|
||||
tm->tm_sec = -tm->tm_sec;
|
||||
tm->tm_min = -tm->tm_min;
|
||||
tm->tm_hour = -tm->tm_hour;
|
||||
tm->tm_mday = -tm->tm_mday;
|
||||
tm->tm_mon = -tm->tm_mon;
|
||||
tm->tm_year = -tm->tm_year;
|
||||
};
|
||||
|
||||
if (tm2timespan(tm, fsec, result) != 0) {
|
||||
elog(WARN,"Unable to decode datetime",NULL);
|
||||
};
|
||||
|
||||
#if FALSE
|
||||
result->time = (fsec2 - fsec1);
|
||||
result->time += (tm2->tm_sec - tm1->tm_sec);
|
||||
result->time += 60*(tm2->tm_min - tm1->tm_min);
|
||||
result->time += 3600*(tm2->tm_hour - tm1->tm_hour);
|
||||
result->time += 86400*(tm2->tm_mday - tm1->tm_mday);
|
||||
|
||||
result->month = 12*(tm2->tm_year - tm1->tm_year);
|
||||
result->month += (tm2->tm_mon - tm1->tm_mon);
|
||||
#endif
|
||||
|
||||
} else {
|
||||
elog(WARN,"Unable to decode datetime",NULL);
|
||||
};
|
||||
|
||||
return(result);
|
||||
} /* datetime_age() */
|
||||
|
||||
|
||||
/*----------------------------------------------------------
|
||||
* Conversion operators.
|
||||
*---------------------------------------------------------*/
|
||||
@ -1016,6 +1136,242 @@ text_timespan(text *str)
|
||||
} /* text_timespan() */
|
||||
|
||||
|
||||
/* datetime_trunc()
|
||||
* Extract specified field from datetime.
|
||||
*/
|
||||
DateTime *
|
||||
datetime_trunc(text *units, DateTime *datetime)
|
||||
{
|
||||
DateTime *result;
|
||||
|
||||
DateTime dt;
|
||||
int tz;
|
||||
int type, val;
|
||||
int i;
|
||||
char *up, *lp, lowunits[MAXDATELEN+1];
|
||||
double fsec;
|
||||
char *tzn;
|
||||
struct tm tt, *tm = &tt;
|
||||
|
||||
if ((!PointerIsValid(units)) || (!PointerIsValid(datetime)))
|
||||
return NULL;
|
||||
|
||||
result = PALLOCTYPE(DateTime);
|
||||
|
||||
up = VARDATA(units);
|
||||
lp = lowunits;
|
||||
for (i = 0; i < (VARSIZE(units)-VARHDRSZ); i++) *lp++ = tolower( *up++);
|
||||
*lp = '\0';
|
||||
|
||||
type = DecodeUnits( 0, lowunits, &val);
|
||||
#if FALSE
|
||||
if (type == IGNORE) {
|
||||
type = DecodeSpecial( 0, lowunits, &val);
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef DATEDEBUG
|
||||
if (type == IGNORE) strcpy(lowunits, "(unknown)");
|
||||
printf( "datetime_trunc- units %s type=%d value=%d\n", lowunits, type, val);
|
||||
#endif
|
||||
|
||||
if (DATETIME_NOT_FINITE(*datetime)) {
|
||||
#if FALSE
|
||||
/* should return null but Postgres doesn't like that currently. - tgl 97/06/12 */
|
||||
elog(WARN,"Datetime is not finite",NULL);
|
||||
#endif
|
||||
*result = 0;
|
||||
|
||||
} else {
|
||||
dt = (DATETIME_IS_RELATIVE(*datetime)? SetDateTime(*datetime): *datetime);
|
||||
|
||||
if ((type == UNITS) && (datetime2tm( dt, &tz, tm, &fsec, &tzn) == 0)) {
|
||||
switch (val) {
|
||||
case DTK_MILLENIUM:
|
||||
tm->tm_year = (tm->tm_year/1000)*1000;
|
||||
case DTK_CENTURY:
|
||||
tm->tm_year = (tm->tm_year/100)*100;
|
||||
case DTK_DECADE:
|
||||
tm->tm_year = (tm->tm_year/10)*10;
|
||||
case DTK_YEAR:
|
||||
tm->tm_mon = 1;
|
||||
case DTK_QUARTER:
|
||||
tm->tm_mon = (3*(tm->tm_mon/4))+1;
|
||||
case DTK_MONTH:
|
||||
tm->tm_mday = 1;
|
||||
case DTK_DAY:
|
||||
tm->tm_hour = 0;
|
||||
case DTK_HOUR:
|
||||
tm->tm_min = 0;
|
||||
case DTK_MINUTE:
|
||||
tm->tm_sec = 0;
|
||||
case DTK_SECOND:
|
||||
fsec = 0;
|
||||
break;
|
||||
|
||||
case DTK_MILLISEC:
|
||||
fsec = rint(fsec*1000)/1000;
|
||||
break;
|
||||
|
||||
case DTK_MICROSEC:
|
||||
fsec = rint(fsec*1000)/1000;
|
||||
break;
|
||||
|
||||
default:
|
||||
elog(WARN,"Datetime units %s not supported",lowunits);
|
||||
result = NULL;
|
||||
};
|
||||
|
||||
if (IS_VALID_UTIME( tm->tm_year, tm->tm_mon, tm->tm_mday)) {
|
||||
#ifdef USE_POSIX_TIME
|
||||
tm->tm_isdst = -1;
|
||||
tm->tm_year -= 1900;
|
||||
tm->tm_mon -= 1;
|
||||
tm->tm_isdst = -1;
|
||||
mktime(tm);
|
||||
tm->tm_year += 1900;
|
||||
tm->tm_mon += 1;
|
||||
|
||||
#ifdef HAVE_INT_TIMEZONE
|
||||
tz = ((tm->tm_isdst > 0)? (timezone - 3600): timezone);
|
||||
|
||||
#else /* !HAVE_INT_TIMEZONE */
|
||||
tz = -(tm->tm_gmtoff); /* tm_gmtoff is Sun/DEC-ism */
|
||||
#endif
|
||||
|
||||
#else /* !USE_POSIX_TIME */
|
||||
tz = CTimeZone;
|
||||
#endif
|
||||
} else {
|
||||
tm->tm_isdst = 0;
|
||||
tz = 0;
|
||||
};
|
||||
|
||||
if (tm2datetime( tm, fsec, &tz, result) != 0)
|
||||
elog(WARN,"Unable to truncate datetime to %s",lowunits);
|
||||
|
||||
#if FALSE
|
||||
} else if ((type == RESERV) && (val == DTK_EPOCH)) {
|
||||
DATETIME_EPOCH(*result);
|
||||
*result = dt - SetDateTime(*result);
|
||||
#endif
|
||||
|
||||
} else {
|
||||
elog(WARN,"Datetime units %s not recognized",lowunits);
|
||||
result = NULL;
|
||||
};
|
||||
};
|
||||
|
||||
return(result);
|
||||
} /* datetime_trunc() */
|
||||
|
||||
/* timespan_trunc()
|
||||
* Extract specified field from timespan.
|
||||
*/
|
||||
TimeSpan *
|
||||
timespan_trunc(text *units, TimeSpan *timespan)
|
||||
{
|
||||
TimeSpan *result;
|
||||
|
||||
int type, val;
|
||||
int i;
|
||||
char *up, *lp, lowunits[MAXDATELEN+1];
|
||||
double fsec;
|
||||
struct tm tt, *tm = &tt;
|
||||
|
||||
if ((!PointerIsValid(units)) || (!PointerIsValid(timespan)))
|
||||
return NULL;
|
||||
|
||||
result = PALLOCTYPE(TimeSpan);
|
||||
|
||||
up = VARDATA(units);
|
||||
lp = lowunits;
|
||||
for (i = 0; i < (VARSIZE(units)-VARHDRSZ); i++) *lp++ = tolower( *up++);
|
||||
*lp = '\0';
|
||||
|
||||
type = DecodeUnits( 0, lowunits, &val);
|
||||
#if FALSE
|
||||
if (type == IGNORE) {
|
||||
type = DecodeSpecial( 0, lowunits, &val);
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef DATEDEBUG
|
||||
if (type == IGNORE) strcpy(lowunits, "(unknown)");
|
||||
printf( "timespan_trunc- units %s type=%d value=%d\n", lowunits, type, val);
|
||||
#endif
|
||||
|
||||
if (TIMESPAN_IS_INVALID(*timespan)) {
|
||||
#if FALSE
|
||||
elog(WARN,"Timespan is not finite",NULL);
|
||||
#endif
|
||||
result = NULL;
|
||||
|
||||
} else if (type == UNITS) {
|
||||
|
||||
if (timespan2tm(*timespan, tm, &fsec) == 0) {
|
||||
switch (val) {
|
||||
case DTK_MILLENIUM:
|
||||
tm->tm_year = (tm->tm_year/1000)*1000;
|
||||
case DTK_CENTURY:
|
||||
tm->tm_year = (tm->tm_year/100)*100;
|
||||
case DTK_DECADE:
|
||||
tm->tm_year = (tm->tm_year/10)*10;
|
||||
case DTK_YEAR:
|
||||
tm->tm_mon = 0;
|
||||
case DTK_QUARTER:
|
||||
tm->tm_mon = (3*(tm->tm_mon/4));
|
||||
case DTK_MONTH:
|
||||
tm->tm_mday = 0;
|
||||
case DTK_DAY:
|
||||
tm->tm_hour = 0;
|
||||
case DTK_HOUR:
|
||||
tm->tm_min = 0;
|
||||
case DTK_MINUTE:
|
||||
tm->tm_sec = 0;
|
||||
case DTK_SECOND:
|
||||
fsec = 0;
|
||||
break;
|
||||
|
||||
case DTK_MILLISEC:
|
||||
fsec = rint(fsec*1000)/1000;
|
||||
break;
|
||||
|
||||
case DTK_MICROSEC:
|
||||
fsec = rint(fsec*1000)/1000;
|
||||
break;
|
||||
|
||||
default:
|
||||
elog(WARN,"Timespan units %s not supported",lowunits);
|
||||
result = NULL;
|
||||
};
|
||||
|
||||
if (tm2timespan(tm, fsec, result) != 0)
|
||||
elog(WARN,"Unable to truncate timespan to %s",lowunits);
|
||||
|
||||
} else {
|
||||
elog(NOTICE,"Timespan out of range",NULL);
|
||||
result = NULL;
|
||||
};
|
||||
|
||||
#if FALSE
|
||||
} else if ((type == RESERV) && (val == DTK_EPOCH)) {
|
||||
*result = timespan->time;
|
||||
if (timespan->month != 0) {
|
||||
*result += ((365.25*86400)*(timespan->month / 12));
|
||||
*result += ((30*86400)*(timespan->month % 12));
|
||||
};
|
||||
#endif
|
||||
|
||||
} else {
|
||||
elog(WARN,"Timespan units %s not recognized",units);
|
||||
result = NULL;
|
||||
};
|
||||
|
||||
return(result);
|
||||
} /* timespan_trunc() */
|
||||
|
||||
|
||||
/* datetime_part()
|
||||
* Extract specified field from datetime.
|
||||
*/
|
||||
@ -1122,9 +1478,24 @@ printf( "datetime_part- units %s type=%d value=%d\n", lowunits, type, val);
|
||||
*result = 0;
|
||||
};
|
||||
|
||||
} else if ((type == RESERV) && (val == DTK_EPOCH)) {
|
||||
DATETIME_EPOCH(*result);
|
||||
*result = dt - SetDateTime(*result);
|
||||
} else if (type == RESERV) {
|
||||
switch (val) {
|
||||
case DTK_EPOCH:
|
||||
DATETIME_EPOCH(*result);
|
||||
*result = dt - SetDateTime(*result);
|
||||
break;
|
||||
|
||||
case DTK_DOW:
|
||||
if (datetime2tm( dt, &tz, tm, &fsec, &tzn) != 0)
|
||||
elog(WARN,"Unable to encode datetime",NULL);
|
||||
|
||||
*result = j2day( date2j( tm->tm_year, tm->tm_mon, tm->tm_mday));
|
||||
break;
|
||||
|
||||
default:
|
||||
elog(WARN,"Datetime units %s not supported",lowunits);
|
||||
*result = 0;
|
||||
};
|
||||
|
||||
} else {
|
||||
elog(WARN,"Datetime units %s not recognized",lowunits);
|
||||
@ -1254,6 +1625,79 @@ printf( "timespan_part- units %s type=%d value=%d\n", lowunits, type, val);
|
||||
} /* timespan_part() */
|
||||
|
||||
|
||||
/* datetime_zone()
|
||||
* Encode datetime type with specified time zone.
|
||||
*/
|
||||
text *
|
||||
datetime_zone(text *zone, DateTime *datetime)
|
||||
{
|
||||
text *result;
|
||||
|
||||
DateTime dt;
|
||||
int tz;
|
||||
int type, val;
|
||||
int i;
|
||||
char *up, *lp, lowzone[MAXDATELEN+1];
|
||||
char *tzn, upzone[MAXDATELEN+1];
|
||||
double fsec;
|
||||
struct tm tt, *tm = &tt;
|
||||
char buf[MAXDATELEN+1];
|
||||
int len;
|
||||
|
||||
if ((!PointerIsValid(zone)) || (!PointerIsValid(datetime)))
|
||||
return NULL;
|
||||
|
||||
up = VARDATA(zone);
|
||||
lp = lowzone;
|
||||
for (i = 0; i < (VARSIZE(zone)-VARHDRSZ); i++) *lp++ = tolower( *up++);
|
||||
*lp = '\0';
|
||||
|
||||
type = DecodeSpecial( 0, lowzone, &val);
|
||||
|
||||
#ifdef DATEDEBUG
|
||||
if (type == IGNORE) strcpy(lowzone, "(unknown)");
|
||||
printf( "datetime_zone- zone %s type=%d value=%d\n", lowzone, type, val);
|
||||
#endif
|
||||
|
||||
if (DATETIME_NOT_FINITE(*datetime)) {
|
||||
/* could return null but Postgres doesn't like that currently. - tgl 97/06/12 */
|
||||
elog(WARN,"Datetime is not finite",NULL);
|
||||
result = NULL;
|
||||
|
||||
} else if ((type == TZ) || (type == DTZ)) {
|
||||
tm->tm_isdst = ((type == DTZ)? 1: 0);
|
||||
tz = val * 60;
|
||||
|
||||
dt = (DATETIME_IS_RELATIVE(*datetime)? SetDateTime(*datetime): *datetime);
|
||||
dt = dt2local( dt, tz);
|
||||
|
||||
if (datetime2tm( dt, NULL, tm, &fsec, NULL) != 0)
|
||||
elog(WARN,"Datetime not legal",NULL);
|
||||
|
||||
up = upzone;
|
||||
lp = lowzone;
|
||||
for (i = 0; *lp != '\0'; i++) *up++ = toupper( *lp++);
|
||||
*up = '\0';
|
||||
|
||||
tzn = upzone;
|
||||
EncodeDateTime(tm, fsec, &tz, &tzn, DateStyle, buf);
|
||||
|
||||
len = (strlen(buf)+VARHDRSZ);
|
||||
|
||||
result = PALLOC(len);
|
||||
|
||||
VARSIZE(result) = len;
|
||||
memmove(VARDATA(result), buf, (len-VARHDRSZ));
|
||||
|
||||
} else {
|
||||
elog(WARN,"Time zone %s not recognized",lowzone);
|
||||
result = NULL;
|
||||
};
|
||||
|
||||
return(result);
|
||||
} /* datetime_zone() */
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* PRIVATE ROUTINES *
|
||||
*****************************************************************************/
|
||||
@ -1307,6 +1751,7 @@ static datetkn datetktbl[] = {
|
||||
{ "dec", MONTH, 12},
|
||||
{ "december", MONTH, 12},
|
||||
{ "dnt", TZ, 6}, /* Dansk Normal Tid */
|
||||
{ "dow", RESERV, DTK_DOW}, /* day of week */
|
||||
{ "dst", DTZMOD, 6},
|
||||
{ "east", TZ, NEG(60)}, /* East Australian Std Time */
|
||||
{ "edt", DTZ, NEG(24)}, /* Eastern Daylight Time */
|
||||
@ -2156,6 +2601,9 @@ printf( " %02d:%02d:%02d\n", tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
if ((*dtype == DTK_DATE) && ((fmask & DTK_DATE_M) == DTK_DATE_M)
|
||||
&& (tzp != NULL) && (! (fmask & DTK_M(TZ)))) {
|
||||
|
||||
/* daylight savings time modifier but no standard timezone? then error */
|
||||
if (fmask & DTK_M(DTZMOD)) return -1;
|
||||
|
||||
if (IS_VALID_UTIME( tm->tm_year, tm->tm_mon, tm->tm_mday)) {
|
||||
#ifdef USE_POSIX_TIME
|
||||
tm->tm_year -= 1900;
|
||||
@ -2669,10 +3117,16 @@ DecodeSpecial(int field, char *lowtoken, int *val)
|
||||
*val = 0;
|
||||
} else {
|
||||
type = tp->type;
|
||||
if ((type == TZ) || (type == DTZ) || (type == DTZMOD)) {
|
||||
switch (type) {
|
||||
case TZ:
|
||||
case DTZ:
|
||||
case DTZMOD:
|
||||
*val = FROMVAL(tp);
|
||||
} else {
|
||||
break;
|
||||
|
||||
default:
|
||||
*val = tp->value;
|
||||
break;
|
||||
};
|
||||
};
|
||||
|
||||
@ -2990,15 +3444,125 @@ printf( "EncodeSpecialDateTime- unrecognized date\n");
|
||||
} /* EncodeSpecialDateTime() */
|
||||
|
||||
|
||||
/* EncodeDateOnly()
|
||||
* Encode date as local time.
|
||||
*/
|
||||
int EncodeDateOnly(struct tm *tm, int style, char *str)
|
||||
{
|
||||
#if FALSE
|
||||
int day;
|
||||
#endif
|
||||
|
||||
if ((tm->tm_mon < 1) || (tm->tm_mon > 12))
|
||||
return -1;
|
||||
|
||||
/* compatible with ISO date formats */
|
||||
if (style == USE_ISO_DATES) {
|
||||
if (tm->tm_year > 0) {
|
||||
sprintf( str, "%04d-%02d-%02d",
|
||||
tm->tm_year, tm->tm_mon, tm->tm_mday);
|
||||
|
||||
} else {
|
||||
sprintf( str, "%04d-%02d-%02d %s",
|
||||
-(tm->tm_year-1), tm->tm_mon, tm->tm_mday, "BC");
|
||||
};
|
||||
|
||||
/* compatible with Oracle/Ingres date formats */
|
||||
} else if (style == USE_SQL_DATES) {
|
||||
if (EuroDates) {
|
||||
sprintf( str, "%02d/%02d", tm->tm_mday, tm->tm_mon);
|
||||
} else {
|
||||
sprintf( str, "%02d/%02d", tm->tm_mon, tm->tm_mday);
|
||||
};
|
||||
if (tm->tm_year > 0) {
|
||||
sprintf( (str+5), "/%04d", tm->tm_year);
|
||||
|
||||
} else {
|
||||
sprintf( (str+5), "/%04d %s", -(tm->tm_year-1), "BC");
|
||||
};
|
||||
|
||||
/* backward-compatible with traditional Postgres abstime dates */
|
||||
} else { /* if (style == USE_POSTGRES_DATES) */
|
||||
|
||||
#if FALSE
|
||||
day = date2j( tm->tm_year, tm->tm_mon, tm->tm_mday);
|
||||
#ifdef DATEDEBUG
|
||||
printf( "EncodeDateOnly- day is %d\n", day);
|
||||
#endif
|
||||
tm->tm_wday = j2day( day);
|
||||
|
||||
strncpy( str, days[tm->tm_wday], 3);
|
||||
strcpy( (str+3), " ");
|
||||
|
||||
if (EuroDates) {
|
||||
sprintf( (str+4), "%02d %3s", tm->tm_mday, months[tm->tm_mon-1]);
|
||||
} else {
|
||||
sprintf( (str+4), "%3s %02d", months[tm->tm_mon-1], tm->tm_mday);
|
||||
};
|
||||
if (tm->tm_year > 0) {
|
||||
sprintf( (str+10), " %04d", tm->tm_year);
|
||||
|
||||
} else {
|
||||
sprintf( (str+10), " %04d %s", -(tm->tm_year-1), "BC");
|
||||
};
|
||||
#endif
|
||||
|
||||
/* traditional date-only style for Postgres */
|
||||
if (EuroDates) {
|
||||
sprintf( str, "%02d-%02d", tm->tm_mday, tm->tm_mon);
|
||||
} else {
|
||||
sprintf( str, "%02d-%02d", tm->tm_mon, tm->tm_mday);
|
||||
};
|
||||
if (tm->tm_year > 0) {
|
||||
sprintf( (str+5), "-%04d", tm->tm_year);
|
||||
|
||||
} else {
|
||||
sprintf( (str+5), "-%04d %s", -(tm->tm_year-1), "BC");
|
||||
};
|
||||
};
|
||||
|
||||
#ifdef DATEDEBUG
|
||||
printf( "EncodeDateOnly- date result is %s\n", str);
|
||||
#endif
|
||||
|
||||
return(TRUE);
|
||||
} /* EncodeDateOnly() */
|
||||
|
||||
|
||||
/* EncodeTimeOnly()
|
||||
* Encode time fields only.
|
||||
*/
|
||||
int EncodeTimeOnly(struct tm *tm, double fsec, int style, char *str)
|
||||
{
|
||||
double sec;
|
||||
|
||||
if ((tm->tm_hour < 0) || (tm->tm_hour > 24))
|
||||
return -1;
|
||||
|
||||
sec = (tm->tm_sec + fsec);
|
||||
|
||||
sprintf( str, "%02d:%02d:", tm->tm_hour, tm->tm_min);
|
||||
sprintf( (str+6), ((fsec != 0)? "%05.2f": "%02.0f"), sec);
|
||||
|
||||
#ifdef DATEDEBUG
|
||||
printf( "EncodeTimeOnly- time result is %s\n", str);
|
||||
#endif
|
||||
|
||||
return(TRUE);
|
||||
} /* EncodeTimeOnly() */
|
||||
|
||||
|
||||
/* EncodeDateTime()
|
||||
* Encode date and time interpreted as local time.
|
||||
*/
|
||||
int EncodeDateTime(struct tm *tm, double fsec, int *tzp, char **tzn, int style, char *str)
|
||||
{
|
||||
char mabbrev[4], dabbrev[4];
|
||||
int day, hour, min;
|
||||
double sec;
|
||||
|
||||
if ((tm->tm_mon < 1) || (tm->tm_mon > 12))
|
||||
return -1;
|
||||
|
||||
sec = (tm->tm_sec + fsec);
|
||||
|
||||
#ifdef DATEDEBUG
|
||||
@ -3016,20 +3580,6 @@ printf( "EncodeDateTime- timezone is %s (%s); offset is %d; daylight is %d\n",
|
||||
#endif
|
||||
#endif
|
||||
|
||||
day = date2j( tm->tm_year, tm->tm_mon, tm->tm_mday);
|
||||
#ifdef DATEDEBUG
|
||||
printf( "EncodeDateTime- day is %d\n", day);
|
||||
#endif
|
||||
tm->tm_wday = j2day( day);
|
||||
|
||||
strncpy( dabbrev, days[tm->tm_wday], 3);
|
||||
dabbrev[3] = '\0';
|
||||
|
||||
if ((tm->tm_mon < 1) || (tm->tm_mon > 12))
|
||||
return -1;
|
||||
|
||||
strcpy( mabbrev, months[tm->tm_mon-1]);
|
||||
|
||||
/* compatible with ISO date formats */
|
||||
if (style == USE_ISO_DATES) {
|
||||
if (tm->tm_year > 0) {
|
||||
@ -3081,11 +3631,19 @@ printf( "EncodeDateTime- day is %d\n", day);
|
||||
|
||||
/* backward-compatible with traditional Postgres abstime dates */
|
||||
} else { /* if (style == USE_POSTGRES_DATES) */
|
||||
sprintf( str, "%3s ", dabbrev);
|
||||
day = date2j( tm->tm_year, tm->tm_mon, tm->tm_mday);
|
||||
#ifdef DATEDEBUG
|
||||
printf( "EncodeDateTime- day is %d\n", day);
|
||||
#endif
|
||||
tm->tm_wday = j2day( day);
|
||||
|
||||
strncpy( str, days[tm->tm_wday], 3);
|
||||
strcpy( (str+3), " ");
|
||||
|
||||
if (EuroDates) {
|
||||
sprintf( (str+4), "%02d %3s", tm->tm_mday, mabbrev);
|
||||
sprintf( (str+4), "%02d %3s", tm->tm_mday, months[tm->tm_mon-1]);
|
||||
} else {
|
||||
sprintf( (str+4), "%3s %02d", mabbrev, tm->tm_mday);
|
||||
sprintf( (str+4), "%3s %02d", months[tm->tm_mon-1], tm->tm_mday);
|
||||
};
|
||||
if (tm->tm_year > 0) {
|
||||
sprintf( (str+10), " %02d:%02d", tm->tm_hour, tm->tm_min);
|
||||
|
@ -3,8 +3,10 @@
|
||||
#include <time.h>
|
||||
#include <ctype.h>
|
||||
#include "postgres.h"
|
||||
#include "miscadmin.h"
|
||||
#include "utils/builtins.h"
|
||||
|
||||
#if FALSE
|
||||
/* copy the next part of the string into a buffer */
|
||||
static const char *
|
||||
cpstr(const char *s, char *buf)
|
||||
@ -29,13 +31,16 @@ cpstr(const char *s, char *buf)
|
||||
buf[in] = 0;
|
||||
return s;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* 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;
|
||||
|
||||
#if FALSE
|
||||
struct tm input_time;
|
||||
char buf[18];
|
||||
const char *p;
|
||||
static const char *mstr[] = {
|
||||
@ -105,6 +110,9 @@ timestamp_in(const char *timestamp_str)
|
||||
|
||||
/* use mktime(), but make this GMT, not local time */
|
||||
result = mktime(&input_time);
|
||||
#endif
|
||||
|
||||
result = nabstimein( (char *) timestamp_str);
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -113,14 +121,24 @@ char *
|
||||
timestamp_out(time_t timestamp)
|
||||
{
|
||||
char *result;
|
||||
struct tm *time;
|
||||
int tz;
|
||||
double fsec = 0;
|
||||
struct tm tt, *tm = &tt;
|
||||
char buf[MAXDATELEN+1];
|
||||
char zone[MAXDATELEN+1], *tzn = zone;
|
||||
|
||||
#if FALSE
|
||||
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,
|
||||
time->tm_hour, time->tm_min, time->tm_sec);
|
||||
#endif
|
||||
abstime2tm( timestamp, &tz, tm, tzn);
|
||||
EncodeDateTime( tm, fsec, &tz, &tzn, USE_ISO_DATES, buf);
|
||||
|
||||
result = palloc(strlen(buf)+1);
|
||||
strcpy( result, buf);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user