java.time
使用 Java 8 及更高版本中内置的 java.time 类。永远不要使用糟糕的遗留日期时间类,例如 Date、Calendar、SimpleDateFormat、GregorianCalendar 和 Timestamp。
从 JDBC 4.2 起,我们可以直接与数据库交换 java.time 对象。
String input = "2014-11-10 04:05:06.999999".replace( " " , "T" ) ; // Convert from SQL style to ISO 8601 standard format where `T` separates the year-month-day portion from hour-minute-second portion.
LocalDateTime ldt = LocalDateTime.parse( input ) ;
没有一刻
请注意,LocalDateTime不是瞬间,不是时间轴上的一个点。您的输入缺少时区或与 UTC 偏移的上下文。因此,我们不知道您的意思是日本东京 10 日凌晨 4 点、法国图卢兹凌晨 4 点,还是美国俄亥俄州托莱多凌晨 4 点——三个非常不同的时刻,在时间轴上相隔几个小时。
因此,您将把 LocalDateTime 对象的值存储在类型为 TIMESTAMP WITHOUT TIME ZONE 的 Postgres 数据库列中。
片刻
如果您的意图是表示一个时刻,时间轴上的一个特定点,那么您最清楚地知道预期的时区。
假设您知道凌晨 4 点是在日本东京时区。将ZoneId 应用于LocalDateTime 以获取ZonedDateTime 对象。
ZoneId z = ZoneId.of( "Asia/Tokyo" ) ;
ZonedDateTime zdt = ldt.atZone( z ) ;
不幸的是,JDBC 4.2 规范不要求支持两种最常用的类型,Instant 和 ZonedDateTime。无论如何,我们都可以轻松转换为OffsetDateTime,这是JDBC规范需要支持的。
OffsetDateTime odt = zdt.toOffsetDateTime() ;
这样一个值,时间线上的一个特定点,应该写入TIMESTAMP WITH TIME ZONE类型的数据库列。
写入数据库。
myPreparedStatement.setObject( … , odt ) ;
和检索。
myResultSet.getObject( … , OffsetDateTime.class ) ;
java.sql.Timestamp
如果您无法迁移到 Java 8,那么您应该使用 JDBC 驱动程序来获取 java.sql.Timestamp 对象。该课程是一个黑客,但它有效。它是一个 java.util.Date 但跟踪小数秒到纳秒而不是毫秒的分辨率。所以它将保留 Postgres 使用的微秒。
您可以将它用作 java.util.Date,但在其他情况下,您将失去额外的分辨率。
但是,您现在真的坚持使用 Java 6、7 还是 2020 年初的版本?最好迁移到 Java 8 或 Java 11,这两个 LTS 版本。
关于java.time
java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.Date、Calendar 和 SimpleDateFormat。
要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310。
Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。
您可以直接与您的数据库交换 java.time 对象。使用符合JDBC 4.2 或更高版本的JDBC driver。不需要字符串,不需要java.sql.* 类。 Hibernate 5 & JPA 2.2 支持 java.time。
从哪里获取 java.time 类?