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 33defc8f9a01..80d9208053b8 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.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,8 +146,7 @@ public FieldType visit(TimestampType timestampType) { public FieldType visit(LocalZonedTimestampType localZonedTimestampType) { int precision = localZonedTimestampType.getPrecision(); TimeUnit timeUnit = getTimeUnit(precision); - ArrowType arrowType = - new ArrowType.Timestamp(timeUnit, ZoneId.systemDefault().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 9b0333f37647..5e7dc9539548 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.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 @@ private byte[] randomBytes(int minLength, int maxLength) { } 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(); + } + } }