diff --git a/velox/functions/lib/DateTimeFormatter.cpp b/velox/functions/lib/DateTimeFormatter.cpp index 09d0f5fb70d6f..d697b86a6104d 100644 --- a/velox/functions/lib/DateTimeFormatter.cpp +++ b/velox/functions/lib/DateTimeFormatter.cpp @@ -1033,7 +1033,7 @@ int32_t DateTimeFormatter::format( bool allowOverflow) const { Timestamp t = timestamp; if (timezone != nullptr) { - t.toTimezone(*timezone); + t.toTimezone(*timezone, allowOverflow); } const auto timePoint = t.toTimePoint(allowOverflow); const auto daysTimePoint = date::floor(timePoint); diff --git a/velox/functions/sparksql/tests/DateTimeFunctionsTest.cpp b/velox/functions/sparksql/tests/DateTimeFunctionsTest.cpp index 131143df3126a..ab68988bbbd57 100644 --- a/velox/functions/sparksql/tests/DateTimeFunctionsTest.cpp +++ b/velox/functions/sparksql/tests/DateTimeFunctionsTest.cpp @@ -887,17 +887,17 @@ TEST_F(DateTimeFunctionsTest, fromUnixtime) { fromUnixTime(getUnixTime("2020-06-30 23:59:59"), "yyyy-MM-dd HH:mm:ss"), "2020-06-30 23:59:59"); + // 8 hours ahead UTC. + setQueryTimeZone("Asia/Shanghai"); // In debug mode, Timestamp constructor will throw exception if range check // fails. #ifdef NDEBUG // Integer overflow in the internal conversion from seconds to milliseconds. EXPECT_EQ( fromUnixTime(std::numeric_limits::max(), "yyyy-MM-dd HH:mm:ss"), - "1969-12-31 23:59:59"); + "1970-01-01 07:59:59"); #endif - // 8 hours ahead UTC. - setQueryTimeZone("Asia/Shanghai"); EXPECT_EQ(fromUnixTime(0, "yyyy-MM-dd HH:mm:ss"), "1970-01-01 08:00:00"); EXPECT_EQ(fromUnixTime(120, "yyyy-MM-dd HH:mm"), "1970-01-01 08:02"); EXPECT_EQ(fromUnixTime(-59, "yyyy-MM-dd HH:mm:ss"), "1970-01-01 07:59:01"); diff --git a/velox/type/Timestamp.cpp b/velox/type/Timestamp.cpp index 257a5a6cd4ff6..1a8a363fbb6c2 100644 --- a/velox/type/Timestamp.cpp +++ b/velox/type/Timestamp.cpp @@ -118,8 +118,8 @@ Timestamp::toTimePoint(bool allowOverflow) const { return tp; } -void Timestamp::toTimezone(const date::time_zone& zone) { - auto tp = toTimePoint(); +void Timestamp::toTimezone(const date::time_zone& zone, bool allowOverflow) { + auto tp = toTimePoint(allowOverflow); auto epoch = zone.to_local(tp).time_since_epoch(); // NOTE: Round down to get the seconds of the current time point. seconds_ = std::chrono::floor(epoch).count(); diff --git a/velox/type/Timestamp.h b/velox/type/Timestamp.h index ebb1bc8fbd4ce..bca5ee54902ca 100644 --- a/velox/type/Timestamp.h +++ b/velox/type/Timestamp.h @@ -316,7 +316,7 @@ struct Timestamp { // Example: Timestamp ts{0, 0}; // ts.Timezone("America/Los_Angeles"); // ts.toString() returns December 31, 1969 16:00:00 - void toTimezone(const date::time_zone& zone); + void toTimezone(const date::time_zone& zone, bool allowOverflow = false); // Same as above, but accepts PrestoDB time zone ID. void toTimezone(int16_t tzID);