Index: src/backend/utils/adt/timestamp.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/utils/adt/timestamp.c,v
retrieving revision 1.165
diff -c -c -r1.165 timestamp.c
*** src/backend/utils/adt/timestamp.c	13 Jul 2006 16:49:16 -0000	1.165
--- src/backend/utils/adt/timestamp.c	26 Aug 2006 02:36:28 -0000
***************
*** 2526,2531 ****
--- 2526,2546 ----
  	result->time = rint(span->time * factor + day_remainder * USECS_PER_DAY);
  #else
  	result->time = span->time * factor + day_remainder * SECS_PER_DAY;
+ 	/*
+ 	 *	The imprecision of float8 causes unusual rounding of even integer
+ 	 *	division, so round up if we have full units.  Check seconds only
+ 	 *	as far as microseconds.
+ 	 */
+ 	if (TSROUND(result->time) == SECS_PER_DAY)
+ 	{
+ 		result->day++;
+ 		result->time = 0;
+ 	}
+ 	if (result->day == DAYS_PER_MONTH)
+ 	{
+ 		result->month++;
+ 		result->day = 0;
+ 	}
  #endif
  
  	PG_RETURN_INTERVAL_P(result);
***************
*** 2579,2584 ****
--- 2594,2614 ----
  	result->time = rint(span->time / factor + day_remainder * USECS_PER_DAY);
  #else
  	result->time = span->time / factor + day_remainder * SECS_PER_DAY;
+ 	/*
+ 	 *	The imprecision of float8 causes unusual rounding of even integer
+ 	 *	division, so round up if we have full units.  Check seconds only
+ 	 *	as far as microseconds.
+ 	 */
+ 	if (TSROUND(result->time) == SECS_PER_DAY)
+ 	{
+ 		result->day++;
+ 		result->time = 0;
+ 	}
+ 	if (result->day == DAYS_PER_MONTH)
+ 	{
+ 		result->month++;
+ 		result->day = 0;
+ 	}
  #endif
  
  	PG_RETURN_INTERVAL_P(result);
