tl;博士
- 使用
java.time.Clock、ZonedDateTime、Instant、ZoneId。
- 将更改后的
Clock 对象作为依赖项注入:Clock.fixed( … )。
- 切勿使用
Date、Calendar、SimpleDateFormat、Timestamp、TimeZone。
将更改后的 Clock 对象作为依赖项传递
您正在使用 terrible 日期时间类,这些类在几年前被 JSR 310 定义的 java.time 类所取代。
java.time.Clock 类提供了几种适合测试的替代行为。这些包括一个固定的时间点、改变的节奏,以及从当前时刻开始的调整。
将这些Clock 对象之一传递给java.time 类中的各种方法,以供您进行测试。
PST 不是时区。以Continent/Region 的格式指定proper time zone name,例如America/Montreal、Africa/Casablanca 或Pacific/Auckland。切勿使用 2-4 个字母的缩写,例如 EST 或 IST,因为它们不是真正的时区,没有标准化,甚至不是唯一的 (!)。
ZoneId z = ZoneId.of( "America/Los_Angeles" ) ;
建立您为测试考虑的特定时刻。
LocalDate ld = LocalDate.of( 2019 , 2 , 11 ) ;
LocalTime lt = LocalTime.MIN ;
ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z ) ;
zdt.toString(): 2019-02-11T00:00-08:00[美国/洛杉矶]
调用Clock.fixed 需要Instant,即UTC 时间。我们可以通过提取Instant 将我们的区域值调整为 UTC。同一时刻,时间轴上的同一点,不同的挂钟时间。
Instant instant = zdt.toInstant() ;
instant.toString(): 2019-02-11T08:00:00Z
指定一个Clock,它将永远将当前时刻报告为该特定时刻,而不增加。
Clock clock = Clock.fixed( instant , z ) ;
clock.toString(): FixedClock[2019-02-11T08:00:00Z,America/Los_Angeles]
将固定时钟作为依赖注入。
Instant now = Instant.now( clock ) ; // Tell me a lie.
now.toString(): 2019-02-11T08:00:00Z
看到这个code run live at IdeOne.com。
JDBC 4.2
如果您要实例化 java.sql.Timestamp 以用于数据库,请改用 java.time 类。从JDBC 4.2 开始,我们可以与数据库交换java.time 对象。
您的JDBC driver 可能有对Instant 的可选支持。
myPreparedStatement.setObject( … , instant ) ; // Storing data.
Instant instant = myResultSet.get( … , Instant.class ) ; // Retrieving data.
您的驱动程序必须支持OffsetDateTime。
myPreparedStatement.setObject( … , instant.atOffset( ZoneOffset.UTC ) ) ; // Storing data.
OffsetDateTime odt = myResultSet.get( … , OffsetDateTime.class ) ; // Retrieving data.
Adjust into a time zone.
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;
关于java.time
java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.Date、Calendar 和 SimpleDateFormat。
Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。
要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310。
您可以直接与您的数据库交换 java.time 对象。使用符合JDBC 4.2 或更高版本的JDBC driver。不需要字符串,不需要java.sql.* 类。
从哪里获得 java.time 类?
ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如Interval、YearWeek、YearQuarter 和more。