This is an automated email from the ASF dual-hosted git repository.
JingsongLi pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/paimon.git
The following commit(s) were added to refs/heads/master by this push:
new 9c0432797b [common] Fix negative time-of-day when casting pre-epoch
timestamp to TIME (#8769)
9c0432797b is described below
commit 9c0432797bb34cf4a24971de0ca88289399d666a
Author: Eunbin Son <[email protected]>
AuthorDate: Tue Jul 21 14:15:10 2026 +0900
[common] Fix negative time-of-day when casting pre-epoch timestamp to TIME
(#8769)
---
.../paimon/casting/TimestampToTimeCastRule.java | 3 ++-
.../apache/paimon/casting/CastExecutorTest.java | 24 ++++++++++++++++++++++
2 files changed, 26 insertions(+), 1 deletion(-)
diff --git
a/paimon-common/src/main/java/org/apache/paimon/casting/TimestampToTimeCastRule.java
b/paimon-common/src/main/java/org/apache/paimon/casting/TimestampToTimeCastRule.java
index ec8822f2b9..cc5c2e1876 100644
---
a/paimon-common/src/main/java/org/apache/paimon/casting/TimestampToTimeCastRule.java
+++
b/paimon-common/src/main/java/org/apache/paimon/casting/TimestampToTimeCastRule.java
@@ -45,7 +45,8 @@ class TimestampToTimeCastRule extends
AbstractCastRule<Timestamp, Number> {
@Override
public CastExecutor<Timestamp, Number> create(DataType inputType, DataType
targetType) {
if (inputType.is(DataTypeRoot.TIMESTAMP_WITHOUT_TIME_ZONE)) {
- return value -> (int) (value.getMillisecond() %
DateTimeUtils.MILLIS_PER_DAY);
+ return value ->
+ (int) Math.floorMod(value.getMillisecond(),
DateTimeUtils.MILLIS_PER_DAY);
} else if (inputType.is(DataTypeRoot.TIMESTAMP_WITH_LOCAL_TIME_ZONE)) {
return value ->
DateTimeUtils.timestampWithLocalZoneToTime(value,
TimeZone.getDefault());
diff --git
a/paimon-common/src/test/java/org/apache/paimon/casting/CastExecutorTest.java
b/paimon-common/src/test/java/org/apache/paimon/casting/CastExecutorTest.java
index 0bcc455986..7a4ddc7097 100644
---
a/paimon-common/src/test/java/org/apache/paimon/casting/CastExecutorTest.java
+++
b/paimon-common/src/test/java/org/apache/paimon/casting/CastExecutorTest.java
@@ -51,6 +51,7 @@ import org.apache.paimon.utils.DecimalUtils;
import org.junit.jupiter.api.Test;
+import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -826,6 +827,29 @@ public class CastExecutorTest {
DateTimeUtils.timestampWithLocalZoneToTime(timestamp,
TimeZone.getDefault()));
}
+ @Test
+ public void testTimestampToTimePreEpoch() {
+ CastExecutor<?, ?> cast = CastExecutors.resolve(new TimestampType(3),
new TimeType(3));
+
+ // pre-epoch 1969-12-31 23:00:00 -> time-of-day 23:00:00 == 82_800_000
ms
+ compareCastResult(
+ cast,
+ Timestamp.fromLocalDateTime(LocalDateTime.of(1969, 12, 31, 23,
0, 0)),
+ 82800000);
+
+ // pre-epoch 1969-12-31 12:34:56.789 -> 12*3600000 + 34*60000 +
56*1000 + 789
+ compareCastResult(
+ cast,
+ Timestamp.fromLocalDateTime(LocalDateTime.of(1969, 12, 31, 12,
34, 56, 789000000)),
+ 45296789);
+
+ // post-epoch 1970-01-01 10:00:00 -> 36_000_000 ms (unchanged behavior)
+ compareCastResult(
+ cast,
+ Timestamp.fromLocalDateTime(LocalDateTime.of(1970, 1, 1, 10,
0, 0)),
+ 36000000);
+ }
+
@Test
public void testDateToTimestamp() {
String date = "2023-06-06";