From: Thomas G. Lockhart Date: Tue, 1 Jul 1997 00:22:46 +0000 (+0000) Subject: Use common parser and encoder for timestamp data type. X-Git-Tag: REL9_0_0~28670 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=8507ddb9c63bc341e52c82acf52770ecd423a994;p=pg-rex%2Fsyncrep.git 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. --- diff --git a/src/backend/utils/adt/datetime.c b/src/backend/utils/adt/datetime.c index 9690dd7fe7..2cf7324275 100644 --- a/src/backend/utils/adt/datetime.c +++ b/src/backend/utils/adt/datetime.c @@ -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); diff --git a/src/backend/utils/adt/dt.c b/src/backend/utils/adt/dt.c index 68051df216..809e39c749 100644 --- a/src/backend/utils/adt/dt.c +++ b/src/backend/utils/adt/dt.c @@ -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); diff --git a/src/backend/utils/adt/timestamp.c b/src/backend/utils/adt/timestamp.c index e884f7eb08..58113955e5 100644 --- a/src/backend/utils/adt/timestamp.c +++ b/src/backend/utils/adt/timestamp.c @@ -3,8 +3,10 @@ #include #include #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; }