不同Presto JDBC版本timestamp值差异原因及修复方案咨询
问题分析与解决方案
根因说明
Presto JDBC驱动在0.82到0.238版本的迭代中,对时间戳类型的时区处理逻辑做了关键调整:
- 0.82及更早版本:驱动会自动将Presto服务器返回的
now()结果(对应服务器时区Africa/Cairo)直接转换为JVM本地时区的时间戳返回,和Hive的行为一致。 - 0.238版本:驱动严格遵循JDBC规范,默认将
TIMESTAMP WITH TIME ZONE类型的返回值以UTC时区解析后转换为Java的Timestamp对象,不再自动继承服务器时区配置,导致解析时出现时区偏移(你的场景中差1小时,对应Africa/Cairo与UTC的时差)。
而from_unixtime()、date_parse()这类函数返回的是基于明确规则生成的时间戳,不受驱动时区解析逻辑变化影响,因此两个版本结果一致。
修复方法
针对presto-jdbc-0.238.jar,可通过以下几种方式修复:
1. JDBC URL中指定时区
在连接URL末尾添加timeZone参数,明确指定服务器使用的Africa/Cairo时区:
java -cp ./presto238/presto-jdbc-0.238.jar:. TestPrestoQuery jdbc:presto://coordinator_hostname:8180/hive/schema?timeZone=Africa/Cairo user
2. 连接属性中设置时区
在代码里给连接Properties添加时区配置,确保驱动以指定时区解析时间:
String url = args[0]; Properties properties = new Properties(); // 添加时区配置 properties.setProperty("timeZone", "Africa/Cairo"); Statement stmt = null; try { Connection connection = DriverManager.getConnection(url, properties); stmt = connection.createStatement(); ResultSet rs = stmt.executeQuery("select now()"); while (rs.next()) { Timestamp tstamp = rs.getTimestamp(1); System.out.println("tstamp -" + tstamp); } } catch (SQLException e ) { System.out.println("Error " + e); } finally { if (stmt != null) { stmt.close(); } }
3. 使用带Calendar参数的getTimestamp方法
在获取结果时,显式传入指定时区的Calendar对象,强制以目标时区解析时间戳:
while (rs.next()) { // 创建Africa/Cairo时区的Calendar Calendar cairoCalendar = Calendar.getInstance(TimeZone.getTimeZone("Africa/Cairo")); Timestamp tstamp = rs.getTimestamp(1, cairoCalendar); System.out.println("tstamp -" + tstamp); }
内容的提问来源于stack exchange,提问作者RaviKumar
相关产品推荐
相关产品推荐

