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)
10741079 TimeADT result ;
10751080
10761081#ifdef HAVE_INT64_TIMESTAMP
1082+ int64 days ;
1083+
10771084 result = 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-
10841096 result = span -> time ;
1085- TMODULO (result , span1 .time , 86400e0 );
1097+ if (result >= 86400e0 || result < 0 )
1098+ result -= floor (result / 86400e0 ) * 86400e0 ;
10861099#endif
10871100
10881101 PG_RETURN_TIMEADT (result );
0 commit comments