diff --git a/src/backend/utils/adt/timestamp.c b/src/backend/utils/adt/timestamp.c index 8f80d9e..70f26b8 100644 --- a/src/backend/utils/adt/timestamp.c +++ b/src/backend/utils/adt/timestamp.c @@ -746,6 +746,11 @@ float8_timestamptz(PG_FUNCTION_ARGS) { float8 seconds = PG_GETARG_FLOAT8(0); TimestampTz result; +#ifdef HAVE_INT64_TIMESTAMP + int64 ts_seconds; + int64 ts_microseconds; +#endif + int64 epoch_diff_seconds; /* Deal with NaN and infinite inputs ... */ if (isnan(seconds)) @@ -776,12 +781,14 @@ float8_timestamptz(PG_FUNCTION_ARGS) errmsg("timestamp out of range: \"%g\"", seconds))); /* Convert UNIX epoch to Postgres epoch */ - seconds -= ((POSTGRES_EPOCH_JDATE - UNIX_EPOCH_JDATE) * SECS_PER_DAY); + epoch_diff_seconds = ((POSTGRES_EPOCH_JDATE - UNIX_EPOCH_JDATE) * SECS_PER_DAY); #ifdef HAVE_INT64_TIMESTAMP - result = seconds * USECS_PER_SEC; + ts_seconds = (int64)seconds; + ts_microseconds = (int64)rint((seconds - ts_seconds) * USECS_PER_SEC); + result = (ts_seconds - epoch_diff_seconds) * USECS_PER_SEC + ts_microseconds; #else - result = seconds; + result = seconds - epoch_diff_seconds; #endif /* Recheck in case roundoff produces something just out of range */