You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@paimon.apache.org by lz...@apache.org on 2026/06/04 08:51:07 UTC

(paimon) branch master updated: [arrow] Fix TIMESTAMP_LTZ Arrow timezone to use UTC instead of system default (#7364)

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 66c2b9caea [arrow] Fix TIMESTAMP_LTZ Arrow timezone to use UTC instead of system default (#7364)
66c2b9caea is described below

commit 66c2b9caeabdb5c5b9c54bbcd5a4d75984d17981
Author: Jiajia Li <pl...@alibaba-inc.com>
AuthorDate: Thu Jun 4 16:51:01 2026 +0800

    [arrow] Fix TIMESTAMP_LTZ Arrow timezone to use UTC instead of system default (#7364)
    
    LocalZonedTimestampType stores UTC timestamps by definition. However,
    ArrowFieldTypeConversion used ZoneId.systemDefault() as the
    ArrowTimestamp timezone.
---
 .../paimon/arrow/ArrowFieldTypeConversion.java      |  6 +-----
 .../paimon/arrow/vector/ArrowFormatWriterTest.java  | 21 +++++++++++++++++++++
 2 files changed, 22 insertions(+), 5 deletions(-)

diff --git a/paimon-arrow/src/main/java/org/apache/paimon/arrow/ArrowFieldTypeConversion.java b/paimon-arrow/src/main/java/org/apache/paimon/arrow/ArrowFieldTypeConversion.java
index 0a72e89304..80d9208053 100644
--- a/paimon-arrow/src/main/java/org/apache/paimon/arrow/ArrowFieldTypeConversion.java
+++ b/paimon-arrow/src/main/java/org/apache/paimon/arrow/ArrowFieldTypeConversion.java
@@ -49,8 +49,6 @@ import org.apache.arrow.vector.types.Types;
 import org.apache.arrow.vector.types.pojo.ArrowType;
 import org.apache.arrow.vector.types.pojo.FieldType;
 
-import java.time.ZoneId;
-
 /** Utils for conversion between Paimon {@link DataType} and Arrow {@link FieldType}. */
 public class ArrowFieldTypeConversion {
 
@@ -148,9 +146,7 @@ public class ArrowFieldTypeConversion {
         public FieldType visit(LocalZonedTimestampType localZonedTimestampType) {
             int precision = localZonedTimestampType.getPrecision();
             TimeUnit timeUnit = getTimeUnit(precision);
-            ArrowType arrowType =
-                    new ArrowType.Timestamp(
-                            timeUnit, ZoneId.systemDefault().normalized().toString());
+            ArrowType arrowType = new ArrowType.Timestamp(timeUnit, "UTC");
             return new FieldType(localZonedTimestampType.isNullable(), arrowType, null);
         }
 
diff --git a/paimon-arrow/src/test/java/org/apache/paimon/arrow/vector/ArrowFormatWriterTest.java b/paimon-arrow/src/test/java/org/apache/paimon/arrow/vector/ArrowFormatWriterTest.java
index 9b0333f376..5e7dc95395 100644
--- a/paimon-arrow/src/test/java/org/apache/paimon/arrow/vector/ArrowFormatWriterTest.java
+++ b/paimon-arrow/src/test/java/org/apache/paimon/arrow/vector/ArrowFormatWriterTest.java
@@ -51,6 +51,8 @@ import org.apache.arrow.vector.VectorSchemaRoot;
 import org.apache.arrow.vector.complex.ListVector;
 import org.apache.arrow.vector.complex.MapVector;
 import org.apache.arrow.vector.complex.StructVector;
+import org.apache.arrow.vector.types.pojo.ArrowType;
+import org.apache.arrow.vector.types.pojo.FieldType;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.ValueSource;
@@ -693,4 +695,23 @@ public class ArrowFormatWriterTest {
         }
         return bytes;
     }
+
+    @Test
+    public void testTimestampArrowFieldTypeTimezone() {
+        for (int precision : new int[] {0, 3, 6, 9}) {
+            // TIMESTAMP_LTZ should use UTC
+            FieldType ltzFieldType =
+                    DataTypes.TIMESTAMP_WITH_LOCAL_TIME_ZONE(precision)
+                            .accept(ArrowFieldTypeConversion.ARROW_FIELD_TYPE_VISITOR);
+            ArrowType.Timestamp ltzType = (ArrowType.Timestamp) ltzFieldType.getType();
+            assertThat(ltzType.getTimezone()).isEqualTo("UTC");
+
+            // TIMESTAMP should have no timezone
+            FieldType tsFieldType =
+                    DataTypes.TIMESTAMP(precision)
+                            .accept(ArrowFieldTypeConversion.ARROW_FIELD_TYPE_VISITOR);
+            ArrowType.Timestamp tsType = (ArrowType.Timestamp) tsFieldType.getType();
+            assertThat(tsType.getTimezone()).isNull();
+        }
+    }
 }