github-actions[bot] commented on code in PR #64029:
URL: https://github.com/apache/doris/pull/64029#discussion_r3341356565


##########
fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/DateTimeExtractAndTransform.java:
##########
@@ -814,8 +818,23 @@ public static Expression convertTz(DateTimeV2Literal 
datetime, StringLikeLiteral
         ZoneId toZone = 
ZoneId.from(zoneFormatter.parse(toTz.getStringValue()));
 
         LocalDateTime localDateTime = datetime.toJavaDateType();
-        ZonedDateTime resultDateTime = 
localDateTime.atZone(fromZone).withZoneSameInstant(toZone);
-        return 
DateTimeV2Literal.fromJavaDateType(resultDateTime.toLocalDateTime(), 
datetime.getDataType().getScale());
+        Instant instant = convertLocalToInstant(localDateTime, fromZone);
+        return 
DateTimeV2Literal.fromJavaDateType(LocalDateTime.ofInstant(instant, toZone),
+                datetime.getDataType().getScale());
+    }
+
+    private static Instant convertLocalToInstant(LocalDateTime localDateTime, 
ZoneId fromZone) {
+        ZoneRules rules = fromZone.getRules();
+        List<ZoneOffset> validOffsets = rules.getValidOffsets(localDateTime);
+        int size = validOffsets.size();
+        // Match BE cctz::convert(civil_second, zone) semantics for constant 
folding.
+        // Normal local time has one offset; repeated local time uses the 
pre-transition offset.
+        if (size == 1 || size == 2) {
+            return localDateTime.atOffset(validOffsets.get(0)).toInstant();
+        }
+        // Skipped local time maps to the transition instant, e.g. 2021-03-28 
02:15 Europe/Paris.
+        ZoneOffsetTransition transition = rules.getTransition(localDateTime);

Review Comment:
   This gap branch drops the DATETIMEV2 fractional part, so FE can still fold a 
different value than BE. In BE, `DateV2Value::unix_timestamp(std::pair<...>)` 
converts the civil second with `cctz::convert(...)` but stores 
`date_v2_value_.microsecond_` separately, and `from_unixtime(std::pair<...>)` 
writes that microsecond back. For example, `convert_tz('2021-03-28 
02:15:00.123456', 'Europe/Paris', 'UTC')` should keep `.123456` on the 
transition instant, while this code returns an `Instant` from 
`transition.getInstant()` with zero nanos and folds to `.000000`. Please 
preserve `localDateTime.getNano()` in the skipped-time path and add a 
fractional DATETIMEV2 gap test.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to