Skip to content

V2 driver ignores column timezones when reading via getTimestamp #2787

Description

@kostya-sh

Description

Steps to reproduce

When running the program below (see Code Example) I get the following output

Table test1 created.
Original Timestamp: 2026-03-12 22:58:08.000 (millis: 1773356288000)
Record inserted.
Read t_tokyo: 2026-03-13 07:58:08.0 (millis: 1773388688000)
Read t_ny:    2026-03-12 18:58:08.0 (millis: 1773341888000)

Note that one Timestamp value is inserted for both columns (as number of millis since epoch so it should be timezone independent) but when read back 2 different values are returned that are not equal to the original one.

I believe the issue is in

public Timestamp getTimestamp(int columnIndex, Calendar cal) throws SQLException {
that completely ignores the column's timezone (zdt.getTimeZone()) and uses JVM default timezone to convert LocalDateTime value to java.sql.Timestamp.

Expected Behaviour

I expect V2 driver to behave the same way as V1 driver and correctly produce 3 identical timestamps:

Table test1 created.
Original Timestamp: 2026-03-12 23:02:25.000 (millis: 1773356545000)
Record inserted.
Read t_tokyo: 2026-03-12 23:02:25.0 (millis: 1773356545000)
Read t_ny:    2026-03-12 23:02:25.0 (millis: 1773356545000)

Code Example

package com.example;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.Timestamp;
import java.util.Properties;

public class App {
    public static void main(String[] args) {
        String url = "jdbc:clickhouse://localhost:8123/default";
        Properties props = new Properties();
        props.setProperty("user", "default");
        props.setProperty("password", "");

        try (Connection conn = DriverManager.getConnection(url, props)) {
            try (Statement stmt = conn.createStatement()) {
                // 1. Create the table
                stmt.execute("DROP TABLE IF EXISTS test1");
                stmt.execute("CREATE TABLE test1 (" +
                             "  t_tokyo DateTime(3, 'Asia/Tokyo'), " +
                             "  t_ny DateTime(3, 'America/New_York') " +
                             ") ENGINE = MergeTree ORDER BY t_tokyo");
                System.out.println("Table test1 created.");
            }

            // 2. Insert record
            Timestamp originalTimestamp = new Timestamp(System.currentTimeMillis());
            System.out.println("Original Timestamp: " + originalTimestamp + " (millis: " + originalTimestamp.getTime() + ")");

            String insertSql = "INSERT INTO test1 (t_tokyo, t_ny) VALUES (?, ?)";
            try (PreparedStatement pstmt = conn.prepareStatement(insertSql)) {
                pstmt.setTimestamp(1, originalTimestamp);
                pstmt.setTimestamp(2, originalTimestamp);
                pstmt.executeUpdate();
                System.out.println("Record inserted.");
            }

            // 3. Read back
            String selectSql = "SELECT t_tokyo, t_ny FROM test1";
            try (Statement stmt = conn.createStatement();
                 ResultSet rs = stmt.executeQuery(selectSql)) {
                if (rs.next()) {
                    Timestamp readTokyo = rs.getTimestamp("t_tokyo");
                    Timestamp readNy = rs.getTimestamp("t_ny");

                    System.out.println("Read t_tokyo: " + readTokyo + " (millis: " + readTokyo.getTime() + ")");
                    System.out.println("Read t_ny:    " + readNy + " (millis: " + readNy.getTime() + ")");
                } else {
                    System.out.println("No record found.");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Environment

  • Client version: 0.9.7
  • Language version: 25
  • OS: Linux

ClickHouse Server

  • ClickHouse Server version: 26.2.3.2
  • ClickHouse Server non-default settings, if any:

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions