diff --git a/velox/functions/prestosql/DateTimeFunctions.h b/velox/functions/prestosql/DateTimeFunctions.h index ae32bb10f23e..d4dc0332a099 100644 --- a/velox/functions/prestosql/DateTimeFunctions.h +++ b/velox/functions/prestosql/DateTimeFunctions.h @@ -275,6 +275,15 @@ struct HourFunction : public InitSessionTimezone { result = getDateTime(date).tm_hour; return true; } + + FOLLY_ALWAYS_INLINE void call( + int64_t& result, + const arg_type& timestampWithTimezone) { + const auto milliseconds = *timestampWithTimezone.template at<0>(); + Timestamp timestamp{milliseconds / kMillisecondsInSecond, 0UL}; + timestamp.toTimezone(*timestampWithTimezone.template at<1>()); + result = getDateTime(timestamp, nullptr).tm_hour; + } }; template diff --git a/velox/functions/prestosql/registration/DateTimeFunctionsRegistration.cpp b/velox/functions/prestosql/registration/DateTimeFunctionsRegistration.cpp index ddd23e93b2d0..29fc0c68dd99 100644 --- a/velox/functions/prestosql/registration/DateTimeFunctionsRegistration.cpp +++ b/velox/functions/prestosql/registration/DateTimeFunctionsRegistration.cpp @@ -46,6 +46,7 @@ void registerSimpleFunctions() { registerFunction({"doy", "day_of_year"}); registerFunction({"hour"}); registerFunction({"hour"}); + registerFunction({"hour"}); registerFunction({"minute"}); registerFunction({"minute"}); registerFunction({"second"}); diff --git a/velox/functions/prestosql/tests/DateTimeFunctionsTest.cpp b/velox/functions/prestosql/tests/DateTimeFunctionsTest.cpp index fc916248c7b2..7720608d049d 100644 --- a/velox/functions/prestosql/tests/DateTimeFunctionsTest.cpp +++ b/velox/functions/prestosql/tests/DateTimeFunctionsTest.cpp @@ -339,6 +339,23 @@ TEST_F(DateTimeFunctionsTest, hour) { // EXPECT_EQ(21, hour(Timestamp(4000000000, 123000000))); EXPECT_EQ(23, hour(Timestamp(998474645, 321000000))); EXPECT_EQ(8, hour(Timestamp(998423705, 321000000))); + + const auto hourWTZ = [&](double timestamp, std::string timeZoneName) { + return evaluateOnce( + "hour(from_unixtime(c0, c1))", + makeRowVector({ + makeNullableFlatVector({timestamp}), + makeNullableFlatVector({timeZoneName}), + })); + }; + EXPECT_EQ(20, hourWTZ(998423705, "+01:00")); + EXPECT_EQ(12, hourWTZ(41028, "+01:00")); + EXPECT_EQ(13, hourWTZ(41028, "+02:00")); + EXPECT_EQ(14, hourWTZ(41028, "+03:00")); + EXPECT_EQ(8, hourWTZ(41028, "-03:00")); + EXPECT_EQ(1, hourWTZ(41028, "+14:00")); + EXPECT_EQ(9, hourWTZ(-100, "-14:00")); + EXPECT_EQ(2, hourWTZ(-41028, "+14:00")); } TEST_F(DateTimeFunctionsTest, hourDate) {