【问题标题】:Is it better to use ResultSet.getString() or ResultSet.getTimestamp() to get a timestamp?使用 ResultSet.getString() 或 ResultSet.getTimestamp() 获取时间戳更好吗?
【发布时间】:2018-12-06 20:41:17
【问题描述】:

在从 Postgres 或 Oracle 检索时间戳时——我们称之为startDate——使用resultSet.getString("startDate") 调用还是resultSet.getTimestamp("startDate") 更好?

目前我正在使用resultSet.getString("startDate"),它工作正常,但我想到使用getTimestamp() 可能是更好的做法。

是否有既定的最佳实践?在时间戳上使用ResultSet.getString() 会不会产生任何意想不到的后果?

【问题讨论】:

  • 仅供参考,java.util.Datejava.util.Calendarjava.text.SimpleDateFormat 等麻烦的旧日期时间类现在已被 java.time 类所取代。大多数 java.time 功能在 ThreeTen-Backport 项目中被反向移植到 Java 6 和 Java 7。进一步适用于ThreeTenABP 中的早期 Android (How to use ThreeTenABP…
  • 您在 Postgres 和 Oracle 中的列的 exact 数据类型是什么? these 中的哪一个完全正确?而且,these 中的哪一个完全正确

标签: java date timestamp resultset


【解决方案1】:

使用 ResultSet.getString() 还是 ResultSet.getTimestamp() 更好 获取时间戳?

都没有。

获取日期时间对象比获取字符串更好,因为这可以更好地表示事物的含义和含义,并且应该更适合 Java 程序中的进一步操作。

同时,使用 java.time 中的现代日期时间类比使用老式 Timestamp 类要好得多。后者存在相当大的设计问题,长期以来一直被认为已过时。

JDBC 驱动程序略有不同,但请查看您是否可以从结果集中获得正确的时间,如 InstantOffsetDateTime,或者如果所有其他方法都失败,则从结果集中获得 LocalDateTime。在所有情况下都使用两个参数getObject 方法。例如:

Instant instant = resultSet.getObject("startDate", Instant.class);

JDBC 4.2 指定应该以这种方式支持 java.time 类。我相信所有当前的 SQL 数据库引擎都有符合 JDBC 4.2 的驱动程序。

仅当您无法使用 Java 8 或更高版本时,请在您的代码中获取 Timestamp。接下来使用来自ThreeTen-Backport 的java.time 类的版本,并使用来自ThreeTen-Backport 的DateTimeUtils 类来转换你的Timestamp,最好是Instant,但如果这恰好给你错误的瞬间,因为时区问题,然后是LocalDateTime。示例:

Instant instant = 
    DateTimeUtils.toInstant(
        resultSet.getTimestamp("startDate")
    )
;

【讨论】:

  • 实际上应该避免使用 Instant,因为 SQL 时间戳值没有指定时区。对于返回 Instant 的 JDBC 驱动程序,它必须假定一个时区或从 JDBC URL 参数中获取它,这在我的经验中是不可靠的。坚持使用 LocalDateTime 可以避免问题并保证准确的数据,而不必依赖 JDBC URL 的时区或服务器时区或客户端时区。
  • @VGR 您的评论不正确。 SQL 标准指定了两种类型的时间戳,一种与时区或与 UTC 的偏移有关,另一种与时区无关。 TIMESTAMP WITH TIME ZONE 关注输入提供的区域/偏移信息,并在检索时发送此类信息。在 Postgres 等许多数据库中,此输入信息用于调整为 UTC,因此检索到的值也是 UTC。一些工具/驱动程序可能会在这样的 UTC 值上注入他们自己对时区的看法,这会使情况复杂化(恕我直言,反功能)。 TIMESTAMP WITHOUT TIME ZONE 没有区域/偏移量。
  • @BasilBourque True,对于 TIMESTAMP WITH TIME ZONE,Instant 或 ZonedDateTime 是合适的。但我看不到那些经常使用的。我想值得问一下 ktm5124 是否是正在使用的类型。 (而且我同意临时区域信息是一种反特征。)
  • @VGR 这么问,在对问题的评论中。
【解决方案2】:

我会使用 resultSet.getTimestamp()。然后您的数据类型从代码正确映射到数据库。如果您愿意,您可以将该结果转换为字符串。我不认为调用resultSet.getString()有时间成本,但通常检索正确的数据类型更合适。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-23
    • 1970-01-01
    • 2018-08-20
    • 2011-08-26
    • 2012-05-29
    • 1970-01-01
    相关资源
    最近更新 更多