diff --git a/be/src/vec/runtime/timestamptz_value.cpp b/be/src/vec/runtime/timestamptz_value.cpp index fae68cf3907a56..d123e2a1e6dfd1 100644 --- a/be/src/vec/runtime/timestamptz_value.cpp +++ b/be/src/vec/runtime/timestamptz_value.cpp @@ -62,8 +62,10 @@ std::string TimestampTzValue::to_string(const cctz::time_zone& tz, int scale) co cctz::civil_second civ = lookup_result.cs; auto time_offset = lookup_result.offset; - int offset_hours = time_offset / 3600; - int offset_mins = (std::abs(time_offset) % 3600) / 60; + bool is_negative_offset = time_offset < 0; + int abs_offset = std::abs(time_offset); + int offset_hours = abs_offset / 3600; + int offset_mins = (abs_offset % 3600) / 60; /// TODO: We could directly use datetime's to_string here. In the future, /// when we support a function like 'show datetime with timezone', @@ -79,13 +81,13 @@ std::string TimestampTzValue::to_string(const cctz::time_zone& tz, int scale) co int len = tmp_dt.to_buffer(buffer, scale); // timezone +03:00 // buffer[len++] = ' '; - buffer[len++] = (offset_hours >= 0 ? '+' : '-'); - buffer[len++] = static_cast('0' + std::abs(offset_hours) / 10); - buffer[len++] = '0' + std::abs(offset_hours) % 10; + buffer[len++] = (is_negative_offset ? '-' : '+'); + buffer[len++] = static_cast('0' + offset_hours / 10); + buffer[len++] = '0' + offset_hours % 10; buffer[len++] = ':'; buffer[len++] = static_cast('0' + offset_mins / 10); buffer[len++] = '0' + offset_mins % 10; - return std::string(buffer, len); + return {buffer, static_cast(len)}; } bool TimestampTzValue::from_datetime(const DateV2Value& origin_dt, diff --git a/be/test/vec/data_types/data_type_timestamptz_test.cpp b/be/test/vec/data_types/data_type_timestamptz_test.cpp index 684a7e20c6b2e4..e046353e1ea211 100644 --- a/be/test/vec/data_types/data_type_timestamptz_test.cpp +++ b/be/test/vec/data_types/data_type_timestamptz_test.cpp @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -100,6 +101,17 @@ TEST_F(DataTypeTimeStampTzTest, test_serder) { } } +TEST_F(DataTypeTimeStampTzTest, test_to_string_negative_sub_hour_offset) { + cctz::time_zone time_zone = cctz::fixed_time_zone(std::chrono::minutes(-30)); + + DateV2Value local_dt; + local_dt.unchecked_set_time(2023, 12, 31, 23, 45, 0, 0); + + TimestampTzValue value; + EXPECT_TRUE(value.from_datetime(local_dt, time_zone, 6, 6)); + EXPECT_EQ(value.to_string(time_zone), "2023-12-31 23:45:00.000000-00:30"); +} + TEST_F(DataTypeTimeStampTzTest, test_sort) { MockRuntimeState _state; RuntimeProfile _profile {"test"};