【问题标题】:java SimpleDateFormat - Correct format for Postgres "timestamp with timezone" date formatjava SimpleDateFormat - Postgres“带时区的时间戳”日期格式的正确格式
【发布时间】:2015-11-19 01:09:58
【问题描述】:

我正在查询 Postgres 数据库并寻找存储 Postgres“带时区的时间戳”信息的最佳方式。

格式为“yyyy-MM-dd' 'HH:mm:ss.SSSzz”(即“2014-04-22 05:39:49.916+03”)

我想使用面向时间戳的类型/类来保存信息(不是字符串)

对于我能想到的所有TIME_FORMATS,以下内容都会引发不可解析的日期:

final String TIME_FORMAT = "yyyy-MM-dd HH:mm:ss.SSSz";
final SimpleDateFormat sdf = new SimpleDateFormat(TIME_FORMAT);
final java.util.Date utilDate = sdf.parse("2014-04-22 05:39:49.916+03");

【问题讨论】:

  • 最后我使用了 java.sql.Timestamp 并且效果很好。而不是将数据库内容作为字符串读取,然后像上面那样构建一个日期(使用 @Codebender 的修复 - 效果很好),我能够将数据库内容(时间戳)读取为 java.sql.Timestamp。
  • 仅供参考,您显示的字符串格式是标准 SQL 日期时间格式。 ISO 8601 标准定义了类似的格式,但将中间的空格替换为 T
  • 目前使用java.sql.Timestamp是正确的方式。当您更新到 JDBC 4.2 驱动程序时,您可以转储 java.sql.Timestamp 类以使用新的 java.time 类型。

标签: java postgresql datetime


【解决方案1】:

你的格式是ISO Timezone,所以使用X(不是z)。

final String TIME_FORMAT = "yyyy-MM-dd HH:mm:ss.SSSX";

More Info here

【讨论】:

  • 最后我使用了 DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.format(Date date);来自 org.apache.commons.lang3.time
【解决方案2】:

java.sql.Timestamp

当前的 JDBC 驱动程序将创建。从 Postgres 的时间戳类型 TIMESTAMP WITH TIME ZONETIMESTAMP WITHOUT TIME ZONE 中检索值时为您提供 java.sql.Timestamp 对象。

java.sql.Timestamp ts = myResultSet.getTimestamp( 1 ) ;

不需要字符串。尽可能坚持使用对象而不是字符串作为日期时间值。

java.time

在 Java 8 及更高版本中,您应该使用新的 java.time 包。避免使用旧的 java.util.Date/.Calendar 等。

当您的 JDBC 驱动程序针对 JDBC 4.2 更新时,您将能够将 Postgres 日期时间值直接检索到 java.time 类型中。

在等待此类驱动程序时,使用添加到 java.sql.Timestamp 的新转换方法转至 tofromInstant.

搜索 StackOverflow 以获取更多信息,因为这已经讨论过很多次了。

【讨论】:

  • 谢谢你的解释!我用的是ibatis,不知道是不是用的JDBC驱动
  • @joeybaruch 你的意思是MyBatis? ibatis是前身,已经退役。两者都是建立在 JDBC 之上的框架。我担心你不知道你的 JDBC 驱动程序。驱动程序之间的行为可能会有所不同,因为 JDBC 规范中并未详细说明每个细节。对于日期时间工作尤其如此。您必须通过数据库了解驱动程序的特定行为。尝试使用一次性代码来学习。不要完全依赖像 MyBatis 这样的框架。
  • 我正在使用 ibatis,事实证明它足以满足我的需要。是的,我不知道我的 JDBC 驱动程序。能否详细说明一下“一次性代码”是什么意思,为什么不依赖 MyBatis 提取 sql 数据?
【解决方案3】:

如果您使用的是 Java 8,则可以将数据存储在 ZonedDateTime object 中,其中存储了一个

带有 ISO-8601 日历系统中时区的日期时间,例如 2007-12-03T10:15:30+01:00 Europe/Paris。

在结果中的 java.sql.Timestamp 值上简单调用 toInstant() 就可以了(感谢 @Basil Bourque 指出这一点)。

在 Java 8 之前,您可以使用现有的解决方案。但请注意,如果您的时区信息存储为 +03,则您的时间格式模式应该以 X 结尾,这是一个 ISO 8601 时区。

【讨论】:

  • 使用ZonedDateTime是可行的方法,但不需要解析。转到 Postgres > JDBC 驱动程序 > java.sql.Timestamp > toInstant 方法 > ZonedDateTime.ofInstant( Instant , ZoneId )。没有任何附加条件。 :-)
猜你喜欢
  • 2020-06-15
  • 1970-01-01
  • 2017-03-28
  • 1970-01-01
  • 2012-07-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-03
相关资源
最近更新 更多