简介
如果要跟踪历史上的某个时刻,请使用Instant
作为类成员变量的类型。具体而言,这个时刻被视为UTC的日期和时间。
public class UserObject() {
Instant createdAt ;
…
public void setCreatedAt( Instant instantArg ) {
this.createdAt = instantArg ;
{
}
使用方法,捕捉当前时刻。
UserObject user = new UserObject() ;
user.setCreatedAt( Instant.now() ) ;
使用方法,从数据库中填充值。
UserObject user = new UserObject() ;
Instant instant = myResultSet.getObject( "when_created" , Instant.class ) ;
user.setCreatedAt( instant ) ;
JDBC 4.2不需要支持Instant
(UTC时间点)。如果你的驱动程序不支持该类,请切换到OffsetDateTime
,该类是必需的。
UserObject user = new UserObject() ;
OffsetDateTime odt = myResultSet.getObject( "when_created" , OffsetDateTime.class ) ;
user.setCreatedAt( odt.toInstant() ) ; // Convert from an `OffsetDateTime` (for any offset-from-UTC) to `Instant` (always in UTC).
![Table of date-time types in Java (both modern and legacy) and in standard SQL.](https://istack.dev59.com/1cse2.webp)
呈现给用户,本地化为用户界面。
user
.getCreatedAt()
.atZone(
ZoneId.of( "Pacific/Auckland" )
)
.format(
DateTimeFormatter.ofLocalizedDateTime(
FormatStyle.FULL
)
.withLocale(
Locale.CANADA_FRENCH
)
)
请注意,
Locale
与时区无关,这是一个正交问题。上面的代码可能适用于来自
Québec并正在旅行
New Zealand的商务人士。她想看到周围
kiwis使用的挂钟时间,但她更喜欢用她的母语法语阅读它的文本显示。时区和语言环境都最好只留给演示;在您的其余代码中通常最好使用UTC。因此,我们将成员变量
createdAt
定义为
Instant
,其中
Instant
根据定义始终处于UTC。
避免使用java.sql.Timestamp
java.sql.Timestamp
与java.sql.Date
、java.util.Date
和Calendar
一起,都是可怕的旧日期时间类的一部分,这些类多年前被java.time类所取代。
- Joda-Time也已被java.time类所取代,正如该项目网站首页所述。
java.time
从JDBC 4.2版本开始,我们可以直接使用java.time对象与数据库进行交互。
Instant
使用Instant
类将当前时刻发送到数据库。Instant
类表示以UTC为基准的时间线上的某一时刻,分辨率为纳秒(最多九位小数)。
Instant instant = Instant.now() ; // Capture the current moment in UTC.
myPreparedStatement.setObject( … , instant ) ;
检索和获取。
Instant instant = myResultSet.getObject( … , Instant.class ) ;
ZonedDateTime
要通过一个特定地区人们使用的挂钟时间(时区)来查看同一时刻,请应用ZoneId
以获取ZonedDateTime
。
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
LocalDateTime
不是一个瞬间
.toLocalDateTime().
当表示特定时间时,永远不要使用LocalDateTime
类。该类故意缺乏任何时区或与UTC的偏移概念。因此,它无法表示瞬间,也不是时间轴上的点。它只是关于可能出现在大约26-27小时范围内的瞬间的模糊想法(时区的范围)。
关于java.time
java.time框架是Java 8及以上版本内置的。这些类取代了老旧的legacy日期时间类,如java.util.Date
, Calendar
和SimpleDateFormat
等,使其更易使用。
欲了解更多信息,请参阅Oracle教程。同时在Stack Overflow上搜索许多示例和解释。规范是JSR 310。
Joda-Time项目现在处于维护模式,建议迁移到java.time类。
您可以直接与数据库交换java.time对象。使用符合JDBC 4.2或更高版本的JDBC驱动程序。无需使用字符串,也不需要java.sql.*
类。Hibernate 5和JPA 2.2支持java.time。
如何获取java.time类?
ZonedDateTime
中显示?然后,举一个错误日期的例子,如在数据库中,本应该是正确的ZonedDateTime
,以及实际结果与正确结果的差异是什么?“在某些情况下,日期是错误的”——坦率地说——这种表述过于模糊。 - Ole V.V.