diff --git a/src/backend/utils/adt/date.c b/src/backend/utils/adt/date.c
index 3b921258890d14fdef817f2d306e18be2162d661..b952480f2fe303991b397203fcc2e89be6b145a3 100644
--- a/src/backend/utils/adt/date.c
+++ b/src/backend/utils/adt/date.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/date.c,v 1.74 2002/11/21 23:31:20 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/date.c,v 1.75 2003/01/09 01:06:57 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -630,12 +630,12 @@ AdjustTimeForTypmod(TimeADT *time, int32 typmod)
 	};
 
 	static const int64 TimeOffsets[MAX_TIMESTAMP_PRECISION + 1] = {
-		INT64CONST(-500000),
-		INT64CONST(-50000),
-		INT64CONST(-5000),
-		INT64CONST(-500),
-		INT64CONST(-50),
-		INT64CONST(-5),
+		INT64CONST(500000),
+		INT64CONST(50000),
+		INT64CONST(5000),
+		INT64CONST(500),
+		INT64CONST(50),
+		INT64CONST(5),
 		INT64CONST(0)
 	};
 
@@ -649,52 +649,33 @@ AdjustTimeForTypmod(TimeADT *time, int32 typmod)
 		100000,
 		1000000
 	};
-
-	static const double TimeOffsets[MAX_TIMESTAMP_PRECISION + 1] = {
-		0.5,
-		0.05,
-		0.005,
-		0.0005,
-		0.00005,
-		0.000005,
-		0.0000005
-	};
 #endif
 
 	if ((typmod >= 0) && (typmod <= MAX_TIME_PRECISION))
 	{
+		/*
+		 * Note: this round-to-nearest code is not completely consistent
+		 * about rounding values that are exactly halfway between integral
+		 * values.  On most platforms, rint() will implement round-to-nearest,
+		 * but the integer code always rounds up (away from zero).  Is it
+		 * worth trying to be consistent?
+		 */
 #ifdef HAVE_INT64_TIMESTAMP
-		/* we have different truncation behavior depending on sign */
 		if (*time >= INT64CONST(0))
-		{
-			*time = ((*time / TimeScales[typmod])
-					 * TimeScales[typmod]);
-		}
-		else
 		{
 			*time = (((*time + TimeOffsets[typmod]) / TimeScales[typmod])
 					 * TimeScales[typmod]);
 		}
-#else
-		/* we have different truncation behavior depending on sign */
-		if (*time >= 0)
-		{
-			*time = (rint(((double) *time) * TimeScales[typmod])
-					 / TimeScales[typmod]);
-		}
 		else
 		{
-			/*
-			 * Scale and truncate first, then add to help the rounding
-			 * behavior
-			 */
-			*time = (rint((((double) *time) * TimeScales[typmod]) + TimeOffsets[typmod])
-					 / TimeScales[typmod]);
+			*time = - ((((- *time) + TimeOffsets[typmod]) / TimeScales[typmod])
+					   * TimeScales[typmod]);
 		}
+#else
+		*time = (rint(((double) *time) * TimeScales[typmod])
+				 / TimeScales[typmod]);
 #endif
 	}
-
-	return;
 }
 
 
diff --git a/src/backend/utils/adt/timestamp.c b/src/backend/utils/adt/timestamp.c
index 885d3992fd44ab5304e7845ab23a89e9507b1a14..19fb9c118438135748919e75ba281b9f7d644ab8 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.75 2002/11/12 00:39:08 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/timestamp.c,v 1.76 2003/01/09 01:06:57 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -175,12 +175,12 @@ AdjustTimestampForTypmod(Timestamp *time, int32 typmod)
 	};
 
 	static const int64 TimestampOffsets[MAX_TIMESTAMP_PRECISION + 1] = {
-		INT64CONST(-500000),
-		INT64CONST(-50000),
-		INT64CONST(-5000),
-		INT64CONST(-500),
-		INT64CONST(-50),
-		INT64CONST(-5),
+		INT64CONST(500000),
+		INT64CONST(50000),
+		INT64CONST(5000),
+		INT64CONST(500),
+		INT64CONST(50),
+		INT64CONST(5),
 		INT64CONST(0)
 	};
 
@@ -194,16 +194,6 @@ AdjustTimestampForTypmod(Timestamp *time, int32 typmod)
 		100000,
 		1000000
 	};
-
-	static const double TimestampOffsets[MAX_TIMESTAMP_PRECISION + 1] = {
-		0.5,
-		0.05,
-		0.005,
-		0.0005,
-		0.00005,
-		0.000005,
-		0.0000005
-	};
 #endif
 
 	if (!TIMESTAMP_NOT_FINITE(*time)
@@ -213,34 +203,27 @@ AdjustTimestampForTypmod(Timestamp *time, int32 typmod)
 			elog(ERROR, "TIMESTAMP(%d) precision must be between %d and %d",
 				 typmod, 0, MAX_TIMESTAMP_PRECISION);
 
+		/*
+		 * Note: this round-to-nearest code is not completely consistent
+		 * about rounding values that are exactly halfway between integral
+		 * values.  On most platforms, rint() will implement round-to-nearest,
+		 * but the integer code always rounds up (away from zero).  Is it
+		 * worth trying to be consistent?
+		 */
 #ifdef HAVE_INT64_TIMESTAMP
-		/* we have different truncation behavior depending on sign */
 		if (*time >= INT64CONST(0))
-		{
-			*time = ((*time / TimestampScales[typmod])
-					 * TimestampScales[typmod]);
-		}
-		else
 		{
 			*time = (((*time + TimestampOffsets[typmod]) / TimestampScales[typmod])
 					 * TimestampScales[typmod]);
 		}
-#else
-		/* we have different truncation behavior depending on sign */
-		if (*time >= 0)
-		{
-			*time = (rint(((double) *time) * TimestampScales[typmod])
-					 / TimestampScales[typmod]);
-		}
 		else
 		{
-			/*
-			 * Scale and truncate first, then add to help the rounding
-			 * behavior
-			 */
-			*time = (rint((((double) *time) * TimestampScales[typmod]) + TimestampOffsets[typmod])
-					 / TimestampScales[typmod]);
+			*time = - ((((- *time) + TimestampOffsets[typmod]) / TimestampScales[typmod])
+					   * TimestampScales[typmod]);
 		}
+#else
+		*time = (rint(((double) *time) * TimestampScales[typmod])
+				 / TimestampScales[typmod]);
 #endif
 	}
 }
@@ -474,12 +457,12 @@ AdjustIntervalForTypmod(Interval *interval, int32 typmod)
 	};
 
 	static const int64 IntervalOffsets[MAX_INTERVAL_PRECISION + 1] = {
-		INT64CONST(-500000),
-		INT64CONST(-50000),
-		INT64CONST(-5000),
-		INT64CONST(-500),
-		INT64CONST(-50),
-		INT64CONST(-5),
+		INT64CONST(500000),
+		INT64CONST(50000),
+		INT64CONST(5000),
+		INT64CONST(500),
+		INT64CONST(50),
+		INT64CONST(5),
 		INT64CONST(0)
 	};
 
@@ -493,16 +476,6 @@ AdjustIntervalForTypmod(Interval *interval, int32 typmod)
 		100000,
 		1000000
 	};
-
-	static const double IntervalOffsets[MAX_INTERVAL_PRECISION + 1] = {
-		0.5,
-		0.05,
-		0.005,
-		0.0005,
-		0.00005,
-		0.000005,
-		0.0000005
-	};
 #endif
 
 	/*
@@ -701,30 +674,27 @@ AdjustIntervalForTypmod(Interval *interval, int32 typmod)
 				elog(ERROR, "INTERVAL(%d) precision must be between %d and %d",
 					 precision, 0, MAX_INTERVAL_PRECISION);
 
+			/*
+			 * Note: this round-to-nearest code is not completely consistent
+			 * about rounding values that are exactly halfway between integral
+			 * values.  On most platforms, rint() will implement round-to-nearest,
+			 * but the integer code always rounds up (away from zero).  Is it
+			 * worth trying to be consistent?
+			 */
 #ifdef HAVE_INT64_TIMESTAMP
-			/* we have different truncation behavior depending on sign */
 			if (interval->time >= INT64CONST(0))
-			{
-				interval->time = ((interval->time / IntervalScales[precision])
-								  * IntervalScales[precision]);
-			}
-			else
 			{
 				interval->time = (((interval->time + IntervalOffsets[precision]) / IntervalScales[precision])
 								  * IntervalScales[precision]);
 			}
-#else
-			/* we have different truncation behavior depending on sign */
-			if (interval->time >= 0)
-			{
-				interval->time = (rint(((double) interval->time) * IntervalScales[precision])
-								  / IntervalScales[precision]);
-			}
 			else
 			{
-				interval->time = (rint((((double) interval->time) + IntervalOffsets[precision])
-				* IntervalScales[precision]) / IntervalScales[precision]);
+				interval->time = - (((-interval->time + IntervalOffsets[precision]) / IntervalScales[precision])
+									* IntervalScales[precision]);
 			}
+#else
+			interval->time = (rint(((double) interval->time) * IntervalScales[precision])
+							  / IntervalScales[precision]);
 #endif
 		}
 	}