Skip to content

Commit 7c82b2e

Browse files
committed
From: Thomas Lockhart <Thomas.G.Lockhart@jpl.nasa.gov>
Subject: [PATCHES] date/time timezone patches (mail bounced?) Here are some hacks to get timezone behavior for the various time data types to be compatible with v6.0. Although we have some hooks already installed to get timezone info from the client to the server, it still isn't clear if that can correctly transfer enough timezone info to make the behavior the same as if timezone info were derived from the server as is now the case. We certainly won't resolve it in a day, so I think we are stuck with server-only timezones for v6.1.
1 parent 9e2a87b commit 7c82b2e

File tree

2 files changed

+69
-20
lines changed

2 files changed

+69
-20
lines changed

src/backend/utils/adt/dt.c

Lines changed: 53 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/dt.c,v 1.15 1997/04/05 02:51:41 scrappy Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/dt.c,v 1.16 1997/04/22 17:36:44 scrappy Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -1400,8 +1400,23 @@ int
14001400
datetime2tm( DateTime dt, int *tzp, struct tm *tm, double *fsec)
14011401
{
14021402
double date, time, sec;
1403+
time_t utime;
1404+
1405+
if (tzp != NULL) {
1406+
/* XXX HACK to get time behavior compatible with Postgres v6.0 - tgl 97/04/07 */
1407+
if ((tm->tm_year > 1902) && (tm->tm_year < 2038)) {
1408+
utime = ((date2j(2000,1,1)-date2j(1970,1,1))*86400+dt);
1409+
localtime((time_t *) &utime);
1410+
#ifdef DATEDEBUG
1411+
printf( "datetime2tm- use system time zone = %ld (CTimeZone = %d)\n", (long int) utime, CTimeZone);
1412+
#endif
1413+
dt = dt2local( dt, timezone);
1414+
1415+
} else {
1416+
dt = dt2local( dt, *tzp);
1417+
};
1418+
};
14031419

1404-
if (tzp != NULL) dt = dt2local( dt, *tzp);
14051420
time = (modf( dt/86400, &date)*86400);
14061421
date += date2j(2000,1,1);
14071422
if (time < 0) {
@@ -1529,9 +1544,9 @@ printf( "tm2timespan- %d %f = %04d-%02d-%02d %02d:%02d:%02d %.2f\n", span->month
15291544
} /* tm2timespan() */
15301545

15311546

1532-
DateTime dt2local(DateTime dt, int timezone)
1547+
DateTime dt2local(DateTime dt, int tz)
15331548
{
1534-
dt -= timezone;
1549+
dt -= tz;
15351550
dt = JROUND(dt);
15361551
return(dt);
15371552
} /* dt2local() */
@@ -1711,6 +1726,8 @@ printf( "DecodeDateTime- field[%d] is %s (type %d)\n", i, field[i], ftype[i]);
17111726

17121727
case DTK_TIME:
17131728
if (DecodeTime(field[i], fmask, &tmask, tm, fsec) != 0) return -1;
1729+
/* check upper limit on hours; other limits checked in DecodeTime() */
1730+
if (tm->tm_hour > 23) return -1;
17141731
break;
17151732

17161733
case DTK_TZ:
@@ -1863,6 +1880,20 @@ printf( " %02d:%02d:%02d\n", tm->tm_hour, tm->tm_min, tm->tm_sec);
18631880
if ((*dtype == DTK_DATE) && ((fmask & DTK_DATE_M) != DTK_DATE_M))
18641881
return(((fmask & DTK_TIME_M) == DTK_TIME_M)? 1: -1);
18651882

1883+
/* timezone not specified? then find local timezone if possible */
1884+
/* XXX HACK to get correct behavior relative to Postgres v6.0 - tgl 97/04/07 */
1885+
if ((*dtype == DTK_DATE) && ((fmask & DTK_DATE_M) == DTK_DATE_M)
1886+
&& (tzp != NULL) && (! (fmask & DTK_M(TZ)))
1887+
&& (tm->tm_year > 1902) && (tm->tm_year < 2038)) {
1888+
tm->tm_year -= 1900;
1889+
tm->tm_mon -= 1;
1890+
mktime(tm);
1891+
tm->tm_year += 1900;
1892+
tm->tm_mon += 1;
1893+
1894+
*tzp = timezone;
1895+
};
1896+
18661897
return 0;
18671898
} /* DecodeDateTime() */
18681899

@@ -2066,6 +2097,8 @@ printf( "DecodeDate- illegal field %s value is %d\n", field[i], val);
20662097

20672098
/* DecodeTime()
20682099
* Decode time string which includes delimiters.
2100+
* Only check the lower limit on hours, since this same code
2101+
* can be used to represent time spans.
20692102
*/
20702103
int
20712104
DecodeTime(char *str, int fmask, int *tmask, struct tm *tm, double *fsec)
@@ -2099,6 +2132,11 @@ DecodeTime(char *str, int fmask, int *tmask, struct tm *tm, double *fsec)
20992132
};
21002133
};
21012134

2135+
/* do a sanity check */
2136+
if ((tm->tm_hour < 0)
2137+
|| (tm->tm_min < 0) || (tm->tm_min > 59)
2138+
|| (tm->tm_sec < 0) || (tm->tm_sec > 59)) return -1;
2139+
21022140
return 0;
21032141
} /* DecodeTime() */
21042142

@@ -2654,6 +2692,9 @@ printf( "EncodeSpecialDateTime- unrecognized date\n");
26542692
} /* EncodeSpecialDateTime() */
26552693

26562694

2695+
/* EncodeDateTime()
2696+
* Encode date and time interpreted as local time.
2697+
*/
26572698
int EncodeDateTime(struct tm *tm, double fsec, int style, char *str)
26582699
{
26592700
char mabbrev[4], dabbrev[4];
@@ -2668,8 +2709,8 @@ int EncodeDateTime(struct tm *tm, double fsec, int style, char *str)
26682709
tm->tm_isdst = -1;
26692710

26702711
#ifdef DATEDEBUG
2671-
printf( "EncodeDateTime- timezone is %s; offset is %d; daylight is %d\n",
2672-
CTZName, CTimeZone, CDayLight);
2712+
printf( "EncodeDateTime- timezone is %s (%s); offset is %ld (%d); daylight is %d (%d)\n",
2713+
tzname[0], CTZName, (long int) timezone, CTimeZone, daylight, CDayLight);
26732714
#endif
26742715

26752716
day = date2j( tm->tm_year, tm->tm_mon, tm->tm_mday);
@@ -2723,10 +2764,8 @@ printf( "EncodeDateTime- day is %d\n", day);
27232764
sprintf( str, "%02d/%02d", tm->tm_mon, tm->tm_mday);
27242765
};
27252766
if (tm->tm_year > 0) {
2726-
sprintf( (str+5), "/%04d %02d:%02d:%5.2f %s",
2767+
sprintf( (str+5), "/%04d %02d:%02d:%05.2f %s",
27272768
tm->tm_year, tm->tm_hour, tm->tm_min, sec, CTZName);
2728-
/* XXX brute-force fill in leading zero on seconds */
2729-
if (*(str+17) == ' ') *(str+17) = '0';
27302769

27312770
} else {
27322771
sprintf( (str+5), "/%04d %02d:%02d %s",
@@ -2742,10 +2781,12 @@ printf( "EncodeDateTime- day is %d\n", day);
27422781
sprintf( (str+4), "%3s %02d", mabbrev, tm->tm_mday);
27432782
};
27442783
if (tm->tm_year > 0) {
2745-
sprintf( (str+10), " %02d:%02d:%5.2f %04d %s",
2784+
#if FALSE
2785+
sprintf( (str+10), " %02d:%02d:%05.2f %04d %s",
27462786
tm->tm_hour, tm->tm_min, sec, tm->tm_year, CTZName);
2747-
/* XXX brute-force fill in leading zero on seconds */
2748-
if (*(str+17) == ' ') *(str+17) = '0';
2787+
#endif
2788+
sprintf( (str+10), " %02d:%02d:%05.2f %04d %s",
2789+
tm->tm_hour, tm->tm_min, sec, tm->tm_year, (daylight? tzname[1]: tzname[0]));
27492790

27502791
} else {
27512792
sprintf( (str+10), " %02d:%02d %04d %s",

src/backend/utils/adt/nabstime.c

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/utils/adt/nabstime.c,v 1.23 1997/04/15 17:46:52 scrappy Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/utils/adt/nabstime.c,v 1.24 1997/04/22 17:36:57 scrappy Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -102,8 +102,16 @@ abstime2tm(AbsoluteTime time, int *tzp, struct tm *tm)
102102
{
103103
struct tm *tt;
104104

105+
#if FALSE
105106
if (tzp != NULL) time -= *tzp;
106107
tt = gmtime((time_t *) &time);
108+
#endif
109+
/* XXX HACK to get time behavior compatible with Postgres v6.0 - tgl 97/04/07 */
110+
if (tzp != NULL) {
111+
tt = localtime((time_t *) &time);
112+
} else {
113+
tt = gmtime((time_t *) &time);
114+
};
107115

108116
tm->tm_year = tt->tm_year+1900;
109117
tm->tm_mon = tt->tm_mon+1;
@@ -160,7 +168,7 @@ tm2abstime( struct tm *tm, int tz)
160168
if (!AbsoluteTimeIsReal(sec))
161169
return(INVALID_ABSTIME);
162170

163-
return sec;
171+
return(sec);
164172
} /* tm2abstime() */
165173

166174

@@ -530,27 +538,27 @@ abstime_datetime(AbsoluteTime abstime)
530538

531539
switch (abstime) {
532540
case INVALID_ABSTIME:
533-
DATETIME_INVALID(*result);
541+
DATETIME_INVALID(*result);
534542
break;
535543

536544
case NOSTART_ABSTIME:
537-
DATETIME_NOBEGIN(*result);
545+
DATETIME_NOBEGIN(*result);
538546
break;
539547

540548
case NOEND_ABSTIME:
541-
DATETIME_NOEND(*result);
549+
DATETIME_NOEND(*result);
542550
break;
543551

544552
case EPOCH_ABSTIME:
545-
DATETIME_EPOCH(*result);
553+
DATETIME_EPOCH(*result);
546554
break;
547555

548556
case CURRENT_ABSTIME:
549-
DATETIME_CURRENT(*result);
557+
DATETIME_CURRENT(*result);
550558
break;
551559

552560
default:
553-
*result = abstime + ((date2j( 1970, 1, 1) - date2j( 2000, 1, 1))*86400);
561+
*result = abstime + ((date2j( 1970, 1, 1) - date2j( 2000, 1, 1))*86400);
554562
break;
555563
};
556564

0 commit comments

Comments
 (0)