8
8
*
9
9
*
10
10
* IDENTIFICATION
11
- * $PostgreSQL: pgsql/src/backend/utils/adt/timestamp.c,v 1.153 2005/09 /09 06:46:14 tgl Exp $
11
+ * $PostgreSQL: pgsql/src/backend/utils/adt/timestamp.c,v 1.154 2005/10 /09 17:21:46 tgl Exp $
12
12
*
13
13
*-------------------------------------------------------------------------
14
14
*/
@@ -998,10 +998,8 @@ dt2time(Timestamp jd, int *hour, int *min, int *sec, fsec_t *fsec)
998
998
* min = time / SECS_PER_MINUTE ;
999
999
time -= (* min ) * SECS_PER_MINUTE ;
1000
1000
* sec = time ;
1001
- * fsec = JROUND ( time - * sec ) ;
1001
+ * fsec = time - * sec ;
1002
1002
#endif
1003
-
1004
- return ;
1005
1003
} /* dt2time() */
1006
1004
1007
1005
@@ -1038,35 +1036,62 @@ timestamp2tm(Timestamp dt, int *tzp, struct pg_tm *tm, fsec_t *fsec, char **tzn,
1038
1036
#endif
1039
1037
}
1040
1038
1041
- time = dt ;
1042
1039
#ifdef HAVE_INT64_TIMESTAMP
1040
+ time = dt ;
1043
1041
TMODULO (time , date , USECS_PER_DAY );
1044
1042
1045
1043
if (time < INT64CONST (0 ))
1046
1044
{
1047
1045
time += USECS_PER_DAY ;
1048
1046
date -= 1 ;
1049
1047
}
1048
+
1049
+ /* add offset to go from J2000 back to standard Julian date */
1050
+ date += POSTGRES_EPOCH_JDATE ;
1051
+
1052
+ /* Julian day routine does not work for negative Julian days */
1053
+ if (date < 0 || date > (Timestamp ) INT_MAX )
1054
+ return -1 ;
1055
+
1056
+ j2date ((int ) date , & tm -> tm_year , & tm -> tm_mon , & tm -> tm_mday );
1057
+ dt2time (time , & tm -> tm_hour , & tm -> tm_min , & tm -> tm_sec , fsec );
1050
1058
#else
1059
+ time = dt ;
1051
1060
TMODULO (time , date , (double )SECS_PER_DAY );
1052
1061
1053
1062
if (time < 0 )
1054
1063
{
1055
1064
time += SECS_PER_DAY ;
1056
- date -= 1 ;
1065
+ date -= 1 ;
1057
1066
}
1058
- #endif
1059
1067
1060
1068
/* add offset to go from J2000 back to standard Julian date */
1061
1069
date += POSTGRES_EPOCH_JDATE ;
1062
1070
1071
+ recalc_d :
1063
1072
/* Julian day routine does not work for negative Julian days */
1064
- if (date < 0 || date > (Timestamp ) INT_MAX )
1073
+ if (date < 0 || date > (Timestamp ) INT_MAX )
1065
1074
return -1 ;
1066
1075
1067
1076
j2date ((int ) date , & tm -> tm_year , & tm -> tm_mon , & tm -> tm_mday );
1077
+ recalc_t :
1068
1078
dt2time (time , & tm -> tm_hour , & tm -> tm_min , & tm -> tm_sec , fsec );
1069
1079
1080
+ * fsec = TSROUND (* fsec );
1081
+ /* roundoff may need to propagate to higher-order fields */
1082
+ if (* fsec >= 1.0 )
1083
+ {
1084
+ time = ceil (time );
1085
+ if (time >= (double )SECS_PER_DAY )
1086
+ {
1087
+ time = 0 ;
1088
+ date += 1 ;
1089
+ goto recalc_d ;
1090
+ }
1091
+ goto recalc_t ;
1092
+ }
1093
+ #endif
1094
+
1070
1095
/* Done if no TZ conversion wanted */
1071
1096
if (tzp == NULL )
1072
1097
{
@@ -1216,9 +1241,17 @@ interval2tm(Interval span, struct pg_tm *tm, fsec_t *fsec)
1216
1241
tm -> tm_sec = time / USECS_PER_SEC ;
1217
1242
* fsec = time - (tm -> tm_sec * USECS_PER_SEC );
1218
1243
#else
1244
+ recalc :
1219
1245
TMODULO (time , tm -> tm_hour , (double )SECS_PER_HOUR );
1220
1246
TMODULO (time , tm -> tm_min , (double )SECS_PER_MINUTE );
1221
1247
TMODULO (time , tm -> tm_sec , 1.0 );
1248
+ time = TSROUND (time );
1249
+ /* roundoff may need to propagate to higher-order fields */
1250
+ if (time >= 1.0 )
1251
+ {
1252
+ time = ceil (span .time );
1253
+ goto recalc ;
1254
+ }
1222
1255
* fsec = time ;
1223
1256
#endif
1224
1257
@@ -1237,8 +1270,7 @@ tm2interval(struct pg_tm *tm, fsec_t fsec, Interval *span)
1237
1270
#else
1238
1271
span -> time = (((tm -> tm_hour * (double )MINS_PER_HOUR ) +
1239
1272
tm -> tm_min ) * (double )SECS_PER_MINUTE ) +
1240
- tm -> tm_sec ;
1241
- span -> time = JROUND (span -> time + fsec );
1273
+ tm -> tm_sec + fsec ;
1242
1274
#endif
1243
1275
1244
1276
return 0 ;
@@ -1266,7 +1298,6 @@ dt2local(Timestamp dt, int tz)
1266
1298
dt -= (tz * USECS_PER_SEC );
1267
1299
#else
1268
1300
dt -= tz ;
1269
- dt = JROUND (dt );
1270
1301
#endif
1271
1302
return dt ;
1272
1303
} /* dt2local() */
@@ -1901,11 +1932,7 @@ timestamp_mi(PG_FUNCTION_ARGS)
1901
1932
(errcode (ERRCODE_DATETIME_VALUE_OUT_OF_RANGE ),
1902
1933
errmsg ("cannot subtract infinite timestamps" )));
1903
1934
1904
- #ifdef HAVE_INT64_TIMESTAMP
1905
1935
result -> time = dt1 - dt2 ;
1906
- #else
1907
- result -> time = JROUND (dt1 - dt2 );
1908
- #endif
1909
1936
1910
1937
result -> month = 0 ;
1911
1938
result -> day = 0 ;
@@ -2224,11 +2251,7 @@ interval_pl(PG_FUNCTION_ARGS)
2224
2251
2225
2252
result -> month = span1 -> month + span2 -> month ;
2226
2253
result -> day = span1 -> day + span2 -> day ;
2227
- #ifdef HAVE_INT64_TIMESTAMP
2228
2254
result -> time = span1 -> time + span2 -> time ;
2229
- #else
2230
- result -> time = JROUND (span1 -> time + span2 -> time );
2231
- #endif
2232
2255
2233
2256
PG_RETURN_INTERVAL_P (result );
2234
2257
}
@@ -2244,11 +2267,7 @@ interval_mi(PG_FUNCTION_ARGS)
2244
2267
2245
2268
result -> month = span1 -> month - span2 -> month ;
2246
2269
result -> day = span1 -> day - span2 -> day ;
2247
- #ifdef HAVE_INT64_TIMESTAMP
2248
2270
result -> time = span1 -> time - span2 -> time ;
2249
- #else
2250
- result -> time = JROUND (span1 -> time - span2 -> time );
2251
- #endif
2252
2271
2253
2272
PG_RETURN_INTERVAL_P (result );
2254
2273
}
@@ -2280,7 +2299,7 @@ interval_mul(PG_FUNCTION_ARGS)
2280
2299
#ifdef HAVE_INT64_TIMESTAMP
2281
2300
result -> time = rint (span -> time * factor + day_remainder * USECS_PER_DAY );
2282
2301
#else
2283
- result -> time = JROUND ( span -> time * factor + day_remainder * SECS_PER_DAY ) ;
2302
+ result -> time = span -> time * factor + day_remainder * SECS_PER_DAY ;
2284
2303
#endif
2285
2304
2286
2305
result = DatumGetIntervalP (DirectFunctionCall1 (interval_justify_hours ,
@@ -2332,7 +2351,6 @@ interval_div(PG_FUNCTION_ARGS)
2332
2351
result -> time += rint (day_remainder * USECS_PER_DAY );
2333
2352
#else
2334
2353
result -> time += day_remainder * SECS_PER_DAY ;
2335
- result -> time = JROUND (result -> time );
2336
2354
#endif
2337
2355
2338
2356
result = DatumGetIntervalP (DirectFunctionCall1 (interval_justify_hours ,
0 commit comments