From 8e9840383c94ee9da264b7b29d85cf2ce4866449 Mon Sep 17 00:00:00 2001
From: "Thomas G. Lockhart" <lockhart@fourpalms.org>
Date: Wed, 17 Jan 2001 16:46:56 +0000
Subject: [PATCH] Change comparisons of tm->tm_isdst from "nonzero" to "greater
 than zero".  Not sure why some were this way, and others were already
 correct, but it  seems to have been like this for several years. This caused
 problems on a few damaged platforms like AIX and IRIX which do  not support
 DST calculations for years before 1970. Thanks to Andreas Zeugswetter
 <ZeugswetterA@wien.spardat.at> for finding  the problem.

---
 src/backend/utils/adt/datetime.c   | 83 ++++++++++++++++--------------
 src/backend/utils/adt/formatting.c |  8 +--
 src/backend/utils/adt/nabstime.c   | 10 ++--
 src/backend/utils/adt/timestamp.c  | 14 ++---
 4 files changed, 60 insertions(+), 55 deletions(-)

diff --git a/src/backend/utils/adt/datetime.c b/src/backend/utils/adt/datetime.c
index 1426088e62b..659cc584ba3 100644
--- a/src/backend/utils/adt/datetime.c
+++ b/src/backend/utils/adt/datetime.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/datetime.c,v 1.57 2000/12/03 20:45:35 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/datetime.c,v 1.58 2001/01/17 16:46:56 thomas Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -2229,21 +2229,27 @@ EncodeTimeSpan(struct tm * tm, double fsec, int style, char *str)
 				sprintf(cp, "%d year%s",
 						tm->tm_year, ((tm->tm_year != 1) ? "s" : ""));
 				cp += strlen(cp);
+				is_before = (tm->tm_year < 0);
 				is_nonzero = TRUE;
 			}
 
 			if (tm->tm_mon != 0)
 			{
-				sprintf(cp, "%s%d mon%s", (is_nonzero ? " " : ""),
+				sprintf(cp, "%s%s%d mon%s", (is_nonzero ? " " : ""),
+						((is_before && (tm->tm_mon > 0)) ? "+" : ""),
 						tm->tm_mon, ((tm->tm_mon != 1) ? "s" : ""));
 				cp += strlen(cp);
+				is_before = (tm->tm_mon < 0);
 				is_nonzero = TRUE;
 			}
 
 			if (tm->tm_mday != 0)
 			{
-				sprintf(cp, "%s%d", (is_nonzero ? " " : ""), tm->tm_mday);
+				sprintf(cp, "%s%s%d day%s", (is_nonzero ? " " : ""),
+						((is_before && (tm->tm_mday > 0)) ? "+" : ""),
+						tm->tm_mday, ((tm->tm_mday != 1) ? "s" : ""));
 				cp += strlen(cp);
+				is_before = (tm->tm_mday < 0);
 				is_nonzero = TRUE;
 			}
 			{
@@ -2251,7 +2257,7 @@ EncodeTimeSpan(struct tm * tm, double fsec, int style, char *str)
 							 || (tm->tm_sec < 0) || (fsec < 0));
 
 				sprintf(cp, "%s%s%02d:%02d", (is_nonzero ? " " : ""),
-						(minus ? "-" : "+"),
+						(minus ? "-" : (is_nonzero ? "+" : "")),
 						abs(tm->tm_hour), abs(tm->tm_min));
 				cp += strlen(cp);
 				/* Mark as "non-zero" since the fields are now filled in */
@@ -2283,59 +2289,59 @@ EncodeTimeSpan(struct tm * tm, double fsec, int style, char *str)
 
 			if (tm->tm_year != 0)
 			{
-				is_before = (tm->tm_year < 0);
-				if (is_before)
-					tm->tm_year = -tm->tm_year;
-				sprintf(cp, "%d year%s",
-						tm->tm_year, ((tm->tm_year != 1) ? "s" : ""));
+				int year = ((tm->tm_year < 0) ? -(tm->tm_year) : tm->tm_year);
+
+				sprintf(cp, "%d year%s", year,
+						((year != 1) ? "s" : ""));
 				cp += strlen(cp);
+				is_before = (tm->tm_year < 0);
 				is_nonzero = TRUE;
 			}
 
 			if (tm->tm_mon != 0)
 			{
+				int mon = ((is_before && (tm->tm_mon > 0)) ? -(tm->tm_mon) : tm->tm_mon);
+
+				sprintf(cp, "%s%d mon%s", (is_nonzero ? " " : ""), mon,
+						((mon != 1) ? "s" : ""));
+				cp += strlen(cp);
 				if (! is_nonzero)
 					is_before = (tm->tm_mon < 0);
-				if (is_before)
-					tm->tm_mon = -tm->tm_mon;
-				sprintf(cp, "%s%d mon%s", (is_nonzero ? " " : ""),
-						tm->tm_mon, ((tm->tm_mon != 1) ? "s" : ""));
-				cp += strlen(cp);
 				is_nonzero = TRUE;
 			}
 
 			if (tm->tm_mday != 0)
 			{
+				int day = ((is_before && (tm->tm_mday > 0)) ? -(tm->tm_mday) : tm->tm_mday);
+
+				sprintf(cp, "%s%d day%s", (is_nonzero ? " " : ""), day,
+						((day != 1) ? "s" : ""));
+				cp += strlen(cp);
 				if (! is_nonzero)
 					is_before = (tm->tm_mday < 0);
-				if (is_before)
-					tm->tm_mday = -tm->tm_mday;
-				sprintf(cp, "%s%d day%s", (is_nonzero ? " " : ""),
-				 tm->tm_mday, ((tm->tm_mday != 1) ? "s" : ""));
-				cp += strlen(cp);
 				is_nonzero = TRUE;
 			}
 			if (tm->tm_hour != 0)
 			{
+				int hour = ((is_before && (tm->tm_hour > 0)) ? -(tm->tm_hour) : tm->tm_hour);
+
+				sprintf(cp, "%s%d hour%s", (is_nonzero ? " " : ""), hour,
+						((hour != 1) ? "s" : ""));
+				cp += strlen(cp);
 				if (! is_nonzero)
 					is_before = (tm->tm_hour < 0);
-				if (is_before)
-					tm->tm_hour = -tm->tm_hour;
-				sprintf(cp, "%s%d hour%s", (is_nonzero ? " " : ""),
-				 tm->tm_hour, ((tm->tm_hour != 1) ? "s" : ""));
-				cp += strlen(cp);
 				is_nonzero = TRUE;
 			}
 
 			if (tm->tm_min != 0)
 			{
+				int min = ((is_before && (tm->tm_min > 0)) ? -(tm->tm_min) : tm->tm_min);
+
+				sprintf(cp, "%s%d min%s", (is_nonzero ? " " : ""), min,
+						((min != 1) ? "s" : ""));
+				cp += strlen(cp);
 				if (! is_nonzero)
 					is_before = (tm->tm_min < 0);
-				if (is_before)
-					tm->tm_min = -tm->tm_min;
-				sprintf(cp, "%s%d min%s", (is_nonzero ? " " : ""),
-				   tm->tm_min, ((tm->tm_min != 1) ? "s" : ""));
-				cp += strlen(cp);
 				is_nonzero = TRUE;
 			}
 
@@ -2343,25 +2349,24 @@ EncodeTimeSpan(struct tm * tm, double fsec, int style, char *str)
 			if (fsec != 0)
 			{
 				fsec += tm->tm_sec;
+				sprintf(cp, "%s%.2f secs", (is_nonzero ? " " : ""),
+						((is_before && (fsec > 0)) ? -(fsec) : fsec));
+				cp += strlen(cp);
 				if (! is_nonzero)
 					is_before = (fsec < 0);
-				if (is_before)
-					fsec = -fsec;
-				sprintf(cp, "%s%.2f secs", (is_nonzero ? " " : ""), fsec);
-				cp += strlen(cp);
 				is_nonzero = TRUE;
 
 				/* otherwise, integer seconds only? */
 			}
 			else if (tm->tm_sec != 0)
 			{
+				int sec = ((is_before && (tm->tm_sec > 0)) ? -(tm->tm_sec) : tm->tm_sec);
+
+				sprintf(cp, "%s%d sec%s", (is_nonzero ? " " : ""), sec,
+						((sec != 1) ? "s" : ""));
+				cp += strlen(cp);
 				if (! is_nonzero)
 					is_before = (tm->tm_sec < 0);
-				if (is_before)
-					tm->tm_sec = -tm->tm_sec;
-				sprintf(cp, "%s%d sec%s", (is_nonzero ? " " : ""),
-				   tm->tm_sec, ((tm->tm_sec != 1) ? "s" : ""));
-				cp += strlen(cp);
 				is_nonzero = TRUE;
 			}
 			break;
@@ -2374,7 +2379,7 @@ EncodeTimeSpan(struct tm * tm, double fsec, int style, char *str)
 		cp += strlen(cp);
 	}
 
-	if (is_before)
+	if (is_before && (style == USE_POSTGRES_DATES))
 	{
 		strcat(cp, " ago");
 		cp += strlen(cp);
diff --git a/src/backend/utils/adt/formatting.c b/src/backend/utils/adt/formatting.c
index 789b7b95130..7996c47f58f 100644
--- a/src/backend/utils/adt/formatting.c
+++ b/src/backend/utils/adt/formatting.c
@@ -1,7 +1,7 @@
 /* -----------------------------------------------------------------------
  * formatting.c
  *
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/formatting.c,v 1.28 2000/12/23 04:05:31 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/formatting.c,v 1.29 2001/01/17 16:46:56 thomas Exp $
  *
  *
  *	 Portions Copyright (c) 1999-2000, PostgreSQL, Inc
@@ -382,7 +382,7 @@ typedef struct {
 		elog(DEBUG_elog_output, "TM:\nsec %d\nyear %d\nmin %d\nwday %d\nhour %d\nyday %d\nmday %d\nnisdst %d\nmon %d\n",\
 			tm->tm_sec, tm->tm_year,\
 			tm->tm_min, tm->tm_wday, tm->tm_hour, tm->tm_yday,\
-			tm->tm_mday, tm->tm_isdst,tm->tm_mon)
+			tm->tm_mday, tm->tm_isdst, tm->tm_mon)
 #endif
 
 #define ZERO_tm( _X ) \
@@ -2933,9 +2933,9 @@ to_timestamp(PG_FUNCTION_ARGS)
 # elif defined(HAVE_INT_TIMEZONE)
 
 #  ifdef __CYGWIN__
-		tz = (tm->tm_isdst ? (_timezone - 3600) : _timezone);
+		tz = ((tm->tm_isdst > 0) ? (_timezone - 3600) : _timezone);
 #  else
-		tz = (tm->tm_isdst ? (timezone - 3600) : timezone);
+		tz = ((tm->tm_isdst > 0) ? (timezone - 3600) : timezone);
 #  endif
 
 # endif
diff --git a/src/backend/utils/adt/nabstime.c b/src/backend/utils/adt/nabstime.c
index e6ad6fc3e29..19c2068fe94 100644
--- a/src/backend/utils/adt/nabstime.c
+++ b/src/backend/utils/adt/nabstime.c
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/nabstime.c,v 1.77 2000/12/09 20:40:57 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/nabstime.c,v 1.78 2001/01/17 16:46:56 thomas Exp $
  *
  * NOTES
  *
@@ -162,9 +162,9 @@ GetCurrentAbsoluteTime(void)
 		CDayLight = tm->tm_isdst;
 		CTimeZone =
 # ifdef __CYGWIN__
-			(tm->tm_isdst ? (_timezone - 3600) : _timezone);
+			((tm->tm_isdst > 0) ? (_timezone - 3600) : _timezone);
 # else
-			(tm->tm_isdst ? (timezone - 3600) : timezone);
+			((tm->tm_isdst > 0) ? (timezone - 3600) : timezone);
 # endif
 		strcpy(CTZName, tzname[tm->tm_isdst]);
 #else /* neither HAVE_TM_ZONE nor HAVE_INT_TIMEZONE */
@@ -245,9 +245,9 @@ abstime2tm(AbsoluteTime _time, int *tzp, struct tm * tm, char *tzn)
 # elif defined(HAVE_INT_TIMEZONE)
 	if (tzp != NULL)
 #  ifdef __CYGWIN__
-		*tzp = (tm->tm_isdst ? (_timezone - 3600) : _timezone);
+		*tzp = ((tm->tm_isdst > 0) ? (_timezone - 3600) : _timezone);
 #  else
-		*tzp = (tm->tm_isdst ? (timezone - 3600) : timezone);
+		*tzp = ((tm->tm_isdst > 0) ? (timezone - 3600) : timezone);
 #  endif
 	if (tzn != NULL)
 	{
diff --git a/src/backend/utils/adt/timestamp.c b/src/backend/utils/adt/timestamp.c
index 436eeb5b4da..144aec0cbe7 100644
--- a/src/backend/utils/adt/timestamp.c
+++ b/src/backend/utils/adt/timestamp.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/timestamp.c,v 1.41 2001/01/03 16:48:02 thomas Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/timestamp.c,v 1.42 2001/01/17 16:46:56 thomas Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -341,9 +341,9 @@ timestamp2tm(Timestamp dt, int *tzp, struct tm * tm, double *fsec, char **tzn)
 				*tzn = (char *) tm->tm_zone;
 # elif defined(HAVE_INT_TIMEZONE)
 #  ifdef __CYGWIN__
-			*tzp = (tm->tm_isdst ? (_timezone - 3600) : _timezone);
+			*tzp = ((tm->tm_isdst > 0) ? (_timezone - 3600) : _timezone);
 #  else
-			*tzp = (tm->tm_isdst ? (timezone - 3600) : timezone);
+			*tzp = ((tm->tm_isdst > 0) ? (timezone - 3600) : timezone);
 #  endif
 			if (tzn != NULL)
 				*tzn = tzname[(tm->tm_isdst > 0)];
@@ -1086,9 +1086,9 @@ timestamp_pl_span(PG_FUNCTION_ARGS)
 # elif defined(HAVE_INT_TIMEZONE)
 
 #  ifdef __CYGWIN__
-					tz = (tm->tm_isdst ? (_timezone - 3600) : _timezone);
+					tz = ((tm->tm_isdst > 0) ? (_timezone - 3600) : _timezone);
 #  else
-					tz = (tm->tm_isdst ? (timezone - 3600) : timezone);
+					tz = ((tm->tm_isdst > 0) ? (timezone - 3600) : timezone);
 #  endif
 
 # endif
@@ -1735,9 +1735,9 @@ timestamp_trunc(PG_FUNCTION_ARGS)
 # elif defined(HAVE_INT_TIMEZONE)
 
 #  ifdef __CYGWIN__
-				tz = (tm->tm_isdst ? (_timezone - 3600) : _timezone);
+				tz = ((tm->tm_isdst > 0) ? (_timezone - 3600) : _timezone);
 #  else
-				tz = (tm->tm_isdst ? (timezone - 3600) : timezone);
+				tz = ((tm->tm_isdst > 0) ? (timezone - 3600) : timezone);
 #  endif
 
 # endif
-- 
GitLab