88 *
99 *
1010 * IDENTIFICATION
11- * $Header: /cvsroot/pgsql/src/backend/utils/adt/date.c,v 1.82 2003/05/12 23:08:50 tgl Exp $
11+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/date.c,v 1.83 2003/06/16 18:56:45 tgl Exp $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
@@ -1066,6 +1066,11 @@ time_interval(PG_FUNCTION_ARGS)
10661066
10671067/* interval_time()
10681068 * Convert interval to time data type.
1069+ *
1070+ * This is defined as producing the fractional-day portion of the interval.
1071+ * Therefore, we can just ignore the months field. It is not real clear
1072+ * what to do with negative intervals, but we choose to subtract the floor,
1073+ * so that, say, '-2 hours' becomes '22:00:00'.
10691074 */
10701075Datum
10711076interval_time (PG_FUNCTION_ARGS )
@@ -1074,15 +1079,23 @@ interval_time(PG_FUNCTION_ARGS)
10741079TimeADT result ;
10751080
10761081#ifdef HAVE_INT64_TIMESTAMP
1082+ int64 days ;
1083+
10771084result = span -> time ;
1078- if ((result >=INT64CONST (86400000000 ))
1079- || (result <=INT64CONST (-86400000000 )))
1080- result -= (result /INT64CONST (1000000 )* INT64CONST (1000000 ));
1085+ if (result >=INT64CONST (86400000000 ))
1086+ {
1087+ days = result /INT64CONST (86400000000 );
1088+ result -= days * INT64CONST (86400000000 );
1089+ }
1090+ else if (result < 0 )
1091+ {
1092+ days = (- result + INT64CONST (86400000000 - 1 )) /INT64CONST (86400000000 );
1093+ result += days * INT64CONST (86400000000 );
1094+ }
10811095#else
1082- Interval span1 ;
1083-
10841096result = span -> time ;
1085- TMODULO (result ,span1 .time ,86400e0 );
1097+ if (result >=86400e0 || result < 0 )
1098+ result -= floor (result /86400e0 )* 86400e0 ;
10861099#endif
10871100
10881101PG_RETURN_TIMEADT (result );