diff --git a/src/backend/utils/adt/nabstime.c b/src/backend/utils/adt/nabstime.c
index f091932074ea92e5240c37c361452133e3145a32..1e7783713e0497732e08c4e3b3f8e376825e32ef 100644
--- a/src/backend/utils/adt/nabstime.c
+++ b/src/backend/utils/adt/nabstime.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *    $Header: /cvsroot/pgsql/src/backend/utils/adt/nabstime.c,v 1.26 1997/05/11 15:11:45 thomas Exp $
+ *    $Header: /cvsroot/pgsql/src/backend/utils/adt/nabstime.c,v 1.27 1997/06/23 14:56:15 thomas Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -97,35 +97,67 @@ GetCurrentTime(struct tm *tm)
 {
     int tz;
 
-    abstime2tm( GetCurrentTransactionStartTime(), &tz, tm);
+    abstime2tm( GetCurrentTransactionStartTime(), &tz, tm, NULL);
 
     return;
 } /* GetCurrentTime() */
 
 
 void
-abstime2tm(AbsoluteTime time, int *tzp, struct tm *tm)
+abstime2tm(AbsoluteTime time, int *tzp, struct tm *tm, char *tzn)
 {
-    struct tm *tt;
+#ifdef USE_POSIX_TIME
+    struct tm *tx;
+#else /* ! USE_POSIX_TIME */
+    struct timeb tb;		/* the old V7-ism */
 
-#if FALSE
-    if (tzp != NULL) time -= *tzp;
-    tt = gmtime((time_t *) &time);
+    (void) ftime(&tb);
 #endif
-    /* XXX HACK to get time behavior compatible with Postgres v6.0 - tgl 97/04/07 */
+
+#ifdef USE_POSIX_TIME
     if (tzp != NULL) {
-	tt = localtime((time_t *) &time);
+	tx = localtime((time_t *) &time);
     } else {
-	tt = gmtime((time_t *) &time);
+	tx = gmtime((time_t *) &time);
     };
+#else
+#endif
+
+#ifdef DATEDEBUG
+#ifdef HAVE_INT_TIMEZONE
+printf( "datetime2tm- (localtime) %d.%02d.%02d %02d:%02d:%02d %s %s dst=%d\n",
+ tx->tm_year, tx->tm_mon, tx->tm_mday, tx->tm_hour, tx->tm_min, tx->tm_sec,
+ tzname[0], tzname[1], tx->tm_isdst);
+#else
+printf( "datetime2tm- (localtime) %d.%02d.%02d %02d:%02d:%02d %s dst=%d\n",
+ tx->tm_year, tx->tm_mon, tx->tm_mday, tx->tm_hour, tx->tm_min, tx->tm_sec,
+ tx->tm_zone, tx->tm_isdst);
+#endif
+#else
+#endif
 
-    tm->tm_year = tt->tm_year+1900;
-    tm->tm_mon = tt->tm_mon+1;
-    tm->tm_mday = tt->tm_mday;
-    tm->tm_hour = tt->tm_hour;
-    tm->tm_min = tt->tm_min;
-    tm->tm_sec = tt->tm_sec;
-    tm->tm_isdst = tt->tm_isdst;
+    tm->tm_year = tx->tm_year+1900;
+    tm->tm_mon = tx->tm_mon+1;
+    tm->tm_mday = tx->tm_mday;
+    tm->tm_hour = tx->tm_hour;
+    tm->tm_min = tx->tm_min;
+    tm->tm_sec = tx->tm_sec;
+    tm->tm_isdst = tx->tm_isdst;
+
+#ifdef USE_POSIX_TIME
+#ifdef HAVE_INT_TIMEZONE
+    if (tzp != NULL) *tzp = (tm->tm_isdst? (timezone - 3600): timezone);
+    if (tzn != NULL) strcpy( tzn, tzname[tm->tm_isdst]);
+#else /* !HAVE_INT_TIMEZONE */
+    if (tzp != NULL) *tzp = - tm->tm_gmtoff;	/* tm_gmtoff is Sun/DEC-ism */
+    /* XXX FreeBSD man pages indicate that this should work - tgl 97/04/23 */
+    if (tzn != NULL) strcpy( tzn, tm->tm_zone);
+#endif
+#else /* ! USE_POSIX_TIME */
+    if (tzp != NULL) *tzp = tb.timezone * 60;
+    /* XXX does this work to get the local timezone string in V7? - tgl 97/03/18 */
+    if (tzn != NULL) strftime( tzn, MAXTZLEN, "%Z", localtime(&now));
+#endif 
 
     return;
 } /* abstime2tm() */
@@ -163,15 +195,6 @@ tm2abstime( struct tm *tm, int tz)
       (day == MIN_DAYNUM && sec > 0))
 	return(INVALID_ABSTIME);
 
-#if FALSE
-    /* daylight correction */
-    if (tm->tm_isdst < 0) {		/* unknown; find out */
-	tm->tm_isdst = (CDayLight > 0);
-    };
-    if (tm->tm_isdst > 0)
-	sec -= 60*60;
-#endif
-
     /* check for reserved values (e.g. "current" on edge of usual range */
     if (!AbsoluteTimeIsReal(sec))
 	return(INVALID_ABSTIME);
@@ -246,22 +269,18 @@ printf( "nabstimein- %d fields are type %d (DTK_DATE=%d)\n", nf, dtype, DTK_DATE
 } /* nabstimein() */
 
 
-/*
+/* nabstimeout()
  * Given an AbsoluteTime return the English text version of the date
  */
 char *
 nabstimeout(AbsoluteTime time)
 {
-    /*
-     * Fri Jan 28 23:05:29 1994 PST
-     * 0        1         2
-     * 12345678901234567890123456789
-     *
-     * we allocate some extra -- timezones are usually 3 characters but
-     * this is not in the POSIX standard...
-     */
-    char buf[40];
     char* result;
+    int tz;
+    double fsec = 0;
+    struct tm tt, *tm = &tt;
+    char buf[MAXDATELEN+1];
+    char zone[MAXDATELEN+1], *tzn = zone;
 
     switch (time) {
     case EPOCH_ABSTIME:	  (void) strcpy(buf, EPOCH);	break;
@@ -270,96 +289,18 @@ nabstimeout(AbsoluteTime time)
     case NOEND_ABSTIME:   (void) strcpy(buf, LATE);	break;
     case NOSTART_ABSTIME: (void) strcpy(buf, EARLY);	break;
     default:
-	/* hack -- localtime happens to work for negative times */
-	(void) strftime(buf, sizeof(buf), "%a %b %d %H:%M:%S %Y %Z",
-			localtime((time_t *) &time));
+	abstime2tm( time, &tz, tm, tzn);
+#if DATEDEBUG
+#endif
+	EncodeDateTime(tm, fsec, &tz, &tzn, DateStyle, buf);
 	break;
     }
-    result = (char*)palloc(strlen(buf) + 1);
-    strcpy(result, buf);
-    return result;
-}
-
 
-/* turn a (struct tm) and a few variables into a time_t, with range checking */
-AbsoluteTime
-dateconv(register struct tm *tm, int zone)
-{
-    tm->tm_wday = tm->tm_yday = 0;
-
-#if FALSE
-    if (tm->tm_year < 70) {
-	tm->tm_year += 2000;
-    } else if (tm->tm_year < 1000) {
-	tm->tm_year += 1900;
-    };
-#endif
-
-    /* validate, before going out of range on some members */
-    if (tm->tm_year < 1901 || tm->tm_year > 2038
-      || tm->tm_mon < 1 || tm->tm_mon > 12
-      || tm->tm_mday < 1 || tm->tm_mday > 31
-      || tm->tm_hour < 0 || tm->tm_hour >= 24
-      || tm->tm_min < 0 || tm->tm_min > 59
-      || tm->tm_sec < 0 || tm->tm_sec > 59)
-	return INVALID_ABSTIME;
-
-    /*
-     * zone should really be -zone, and tz should be set to tp->value, not
-     * -tp->value.  Or the table could be fixed.
-     */
-    tm->tm_sec += zone;		/* mktime lets it be out of range */
-
-    /* convert to seconds */
-    return qmktime(tm);
-}
-
-
-/*
- * near-ANSI qmktime suitable for use by dateconv; not necessarily as paranoid
- * as ANSI requires, and it may not canonicalise the struct tm.  Ignores tm_wday
- * and tm_yday.
- */
-time_t
-qmktime(struct tm *tm)
-{
-    time_t sec;
-
-    int day;
-
-#if FALSE
-    /* If it was a 2 digit year */
-    if (tm->tm_year < 100)
-	tm->tm_year += 1900;
-#endif
-
-    day = (date2j( tm->tm_year, tm->tm_mon, tm->tm_mday) - date2j( 1970, 1, 1));
-
-    /* check for time out of range */
-    if ((day < MIN_DAYNUM) || (day > MAX_DAYNUM))
-	return INVALID_ABSTIME;
-
-    /* convert to seconds */
-    sec = tm->tm_sec + (tm->tm_min +(day*24 + tm->tm_hour)*60)*60;
-
-    /* check for overflow */
-    if ((day == MAX_DAYNUM && sec < 0) ||
-	(day == MIN_DAYNUM && sec > 0))
-	return INVALID_ABSTIME;
-
-    /* check for reserved values (e.g. "current" on edge of usual range */
-    if (!AbsoluteTimeIsReal(sec))
-	return INVALID_ABSTIME;
-
-    /* daylight correction */
-    if (tm->tm_isdst < 0) {		/* unknown; find out */
-	tm->tm_isdst = (CDayLight > 0);
-    };
-    if (tm->tm_isdst > 0)
-	sec -= 60*60;
+    result = PALLOC(strlen(buf) + 1);
+    strcpy(result, buf);
 
-    return sec;
-} /* qmktime() */
+    return(result);
+} /* nabstimeout() */
 
 
 /*