This is an automated email from the ASF dual-hosted git repository.
morrysnow pushed a commit to branch branch-3.1
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/branch-3.1 by this push:
new 1d8f09a369f branch-3.1: [fix](timezone) Fix incorrect DST handling
#51454 (#52420)
1d8f09a369f is described below
commit 1d8f09a369f4a254859dd326a8c2a839b12d04a6
Author: zclllyybb <[email protected]>
AuthorDate: Sat Jun 28 22:52:30 2025 +0800
branch-3.1: [fix](timezone) Fix incorrect DST handling #51454 (#52420)
Cherry-pick from #51454
---
be/src/vec/runtime/vdatetime_value.cpp | 57 +++++++++------------
be/src/vec/runtime/vdatetime_value.h | 20 ++++----
.../data/datatype_p0/datetimev2/test_timezone.out | Bin 628 -> 434 bytes
.../datatype_p0/datetimev2/test_tz_streamload.out | Bin 627 -> 627 bytes
.../datatype_p0/datetimev2/test_timezone.groovy | 5 ++
5 files changed, 38 insertions(+), 44 deletions(-)
diff --git a/be/src/vec/runtime/vdatetime_value.cpp
b/be/src/vec/runtime/vdatetime_value.cpp
index d161c64fd1f..ef6aa7e95eb 100644
--- a/be/src/vec/runtime/vdatetime_value.cpp
+++ b/be/src/vec/runtime/vdatetime_value.cpp
@@ -2041,7 +2041,7 @@ bool DateV2Value<T>::from_date_str_base(const char*
date_str, int len, int scale
int field_idx = 0;
int field_len = year_len;
- long sec_offset = 0;
+ int sec_offset = 0;
bool need_use_timezone = false;
while (ptr < end && isdigit(*ptr) && field_idx < MAX_DATE_PARTS) {
@@ -2206,40 +2206,29 @@ bool DateV2Value<T>::from_date_str_base(const char*
date_str, int len, int scale
if (!TimezoneUtils::find_cctz_time_zone(std::string {ptr, end},
given_tz)) {
return false; // invalid format
}
- auto given = cctz::convert(cctz::civil_second {}, given_tz);
- auto local = cctz::convert(cctz::civil_second {}, *local_time_zone);
- // these two values is absolute time. so they are negative. need to
use (-local) - (-given)
- sec_offset = std::chrono::duration_cast<std::chrono::seconds>(given -
local).count();
- }
-
- // In check_range_and_set_time, for Date type the time part will be
truncated. So if the timezone offset should make
- // rounding to date part, it would be lost. To avoid this, we use a
Datetime type to do these calc. It will save the
- // time part and apply the offset. Then convert to Date type back.
- // see https://github.com/apache/doris/pull/33553 for more details.
- if constexpr (!is_datetime) {
- if (sec_offset) {
- DateV2Value<DateTimeV2ValueType> tmp;
- if (!tmp.check_range_and_set_time(date_val[0], date_val[1],
date_val[2], date_val[3],
- date_val[4], date_val[5],
date_val[6])) {
- return false;
- }
- if (!tmp.date_add_interval<TimeUnit::SECOND>(
- TimeInterval {TimeUnit::SECOND, sec_offset, false})) {
- return false;
- }
- this->assign_from(tmp);
- return true;
+ if (is_invalid(date_val[0], date_val[1], date_val[2], date_val[3],
date_val[4], date_val[5],
+ date_val[6])) {
+ return false;
}
- }
-
- if (!check_range_and_set_time(date_val[0], date_val[1], date_val[2],
date_val[3], date_val[4],
- date_val[5], date_val[6])) {
- return false;
- }
-
- return sec_offset ? date_add_interval<TimeUnit::SECOND>(
- TimeInterval {TimeUnit::SECOND, sec_offset,
false})
- : true;
+ // will carring on the bits in cctz::civil_second. if day is 70, will
carry to month.
+ cctz::civil_second cs {date_val[0], date_val[1], date_val[2],
+ date_val[3], date_val[4], date_val[5]};
+
+ auto given = cctz::convert(cs, given_tz);
+ auto local = cctz::convert(given, *local_time_zone);
+ date_val[0] = local.year();
+ date_val[1] = local.month();
+ date_val[2] = local.day();
+ date_val[3] = local.hour();
+ date_val[4] = local.minute();
+ date_val[5] = local.second();
+ }
+
+ return check_range_and_set_time(date_val[0], date_val[1], date_val[2],
date_val[3], date_val[4],
+ date_val[5], date_val[6]) &&
+ (sec_offset ? date_add_interval<TimeUnit::SECOND>(
+ TimeInterval {TimeUnit::SECOND, sec_offset,
false})
+ : true);
}
template <typename T>
diff --git a/be/src/vec/runtime/vdatetime_value.h
b/be/src/vec/runtime/vdatetime_value.h
index b337fea46a2..12e961f5fa9 100644
--- a/be/src/vec/runtime/vdatetime_value.h
+++ b/be/src/vec/runtime/vdatetime_value.h
@@ -1024,8 +1024,8 @@ public:
}
bool operator==(const VecDateTimeValue& other) const {
- int64_t ts1;
- int64_t ts2;
+ int64_t ts1 = 0;
+ int64_t ts2 = 0;
this->unix_timestamp(&ts1, TimezoneUtils::default_time_zone);
other.unix_timestamp(&ts2, TimezoneUtils::default_time_zone);
return ts1 == ts2;
@@ -1040,8 +1040,8 @@ public:
bool operator<=(const DateV2Value<T>& other) const { return !(*this >
other); }
bool operator<=(const VecDateTimeValue& other) const {
- int64_t ts1;
- int64_t ts2;
+ int64_t ts1 = 0;
+ int64_t ts2 = 0;
this->unix_timestamp(&ts1, TimezoneUtils::default_time_zone);
other.unix_timestamp(&ts2, TimezoneUtils::default_time_zone);
return ts1 <= ts2;
@@ -1050,8 +1050,8 @@ public:
bool operator>=(const DateV2Value<T>& other) const { return !(*this <
other); }
bool operator>=(const VecDateTimeValue& other) const {
- int64_t ts1;
- int64_t ts2;
+ int64_t ts1 = 0;
+ int64_t ts2 = 0;
this->unix_timestamp(&ts1, TimezoneUtils::default_time_zone);
other.unix_timestamp(&ts2, TimezoneUtils::default_time_zone);
return ts1 >= ts2;
@@ -1062,8 +1062,8 @@ public:
}
bool operator<(const VecDateTimeValue& other) const {
- int64_t ts1;
- int64_t ts2;
+ int64_t ts1 = 0;
+ int64_t ts2 = 0;
this->unix_timestamp(&ts1, TimezoneUtils::default_time_zone);
other.unix_timestamp(&ts2, TimezoneUtils::default_time_zone);
return ts1 < ts2;
@@ -1074,8 +1074,8 @@ public:
}
bool operator>(const VecDateTimeValue& other) const {
- int64_t ts1;
- int64_t ts2;
+ int64_t ts1 = 0;
+ int64_t ts2 = 0;
this->unix_timestamp(&ts1, TimezoneUtils::default_time_zone);
other.unix_timestamp(&ts2, TimezoneUtils::default_time_zone);
return ts1 > ts2;
diff --git a/regression-test/data/datatype_p0/datetimev2/test_timezone.out
b/regression-test/data/datatype_p0/datetimev2/test_timezone.out
index 1fae14def39..6b1b3ebb41d 100644
Binary files a/regression-test/data/datatype_p0/datetimev2/test_timezone.out
and b/regression-test/data/datatype_p0/datetimev2/test_timezone.out differ
diff --git a/regression-test/data/datatype_p0/datetimev2/test_tz_streamload.out
b/regression-test/data/datatype_p0/datetimev2/test_tz_streamload.out
index ab103c3a306..a05ac54d305 100644
Binary files
a/regression-test/data/datatype_p0/datetimev2/test_tz_streamload.out and
b/regression-test/data/datatype_p0/datetimev2/test_tz_streamload.out differ
diff --git a/regression-test/suites/datatype_p0/datetimev2/test_timezone.groovy
b/regression-test/suites/datatype_p0/datetimev2/test_timezone.groovy
index 746a78de441..5d3d7c272ca 100644
--- a/regression-test/suites/datatype_p0/datetimev2/test_timezone.groovy
+++ b/regression-test/suites/datatype_p0/datetimev2/test_timezone.groovy
@@ -43,4 +43,9 @@ suite("test_timezone") {
qt_fold1 """ select cast('2020-12-12T12:12:12asia/shanghai' as datetime);
"""
qt_fold2 """ select cast('2020-12-12T12:12:12america/los_angeLES' as
datetime); """
qt_fold3 """ select cast('2020-12-12T12:12:12Europe/pARIS' as datetime);
"""
+
+ qt_nodst "select cast('2010-01-05 08:15:30Europe/London' as datetime);"
+ qt_dst "select cast('2010-08-05 08:15:30Europe/London' as datetime);"
+ testFoldConst ("select cast('2010-01-05 08:15:30Europe/London' as
datetime);")
+ testFoldConst ("select cast('2010-08-05 08:15:30Europe/London' as
datetime);")
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]