简而言之
Duration // Span of time, with resolution of nanoseconds.
.between( // Calculate elapsed time.
LocalTime.now( // Get current time-of-day…
ZoneId.of( "Pacific/Auckland" ) // … as seen in a particular time zone.
) // Returns a `LocalTime` object.
,
myJavaUtilDate // Avoid terrible legacy date-time classes such as `java.util.Date`.
.toInstant() // Convert from `java.util.Date` to `java.time.Instant`, both representing a moment in UTC.
.atZone( // Adjust from UTC to a particular time zone. Same moment, same point on the timeline, different wall-clock time.
ZoneId.of( "Pacific/Auckland" ) // Specify time zone by proper naming in `Continent/Region` format, never 2-4 letter pseudo-zones such as `PST`, `CEST`, `CST`, `IST`, etc.
) // Returns a `ZonedDateTime` object.
.toLocalTime() // Extract the time-of-day without the date and without a time zone.
) // Returns a `Duration` object.
.toMillis() // Calculate entire span-of-time in milliseconds. Beware of data-loss as `Instant` uses a finer resolution the milliseconds, and may carry microseconds or nanoseconds.
我建议传递类型安全且自解释的
Duration
对象,而不是仅仅传递毫秒数的整数。
java.time
现代方法使用
java.time类,取代了可怕的遗留类,如
Date
、
Calendar
、
SimpleDateFormat
。
将您的
java.util.Date
(UTC中的一个时刻)转换为
Instant
。使用添加到旧类中的新转换方法。
Instant instant = myJavaUtilDate.toInstant() ;
那表示UTC时间的一个时刻。确定日期和时间需要一个
时区。对于任何给定时刻,日期和时间因时区而在全球范围内变化。例如,在
法国巴黎的午夜后几分钟是新的一天,而在
加拿大魁北克省蒙特利尔仍然是“昨天”。
如果未指定时区,则JVM隐式应用其当前默认时区。该默认值可能会在运行时的任何时刻
更改,因此您的结果可能会有所不同。最好将
所需/期望的时区明确指定为参数。
请使用格式为大陆/地区
的正确时区名称,例如America/Montreal
、Africa/Casablanca
或Pacific/Auckland
。绝不要使用2-4个字母的缩写,如EST
或IST
,因为它们不是真正的时区,没有标准化,甚至不唯一(!)。
ZoneId z = ZoneId.of( "America/Montreal" ) ;
如果您想使用JVM的当前默认时区,请请求并将其作为参数传递。如果省略,则隐式应用JVM的当前默认值。最好明确说明,因为默认值可能在运行时由JVM中任何应用程序的任何线程中的任何代码在任何时刻更改。
ZoneId z = ZoneId.systemDefault() ; // Get JVM’s current default time zone.
将
ZoneId
分配给
Instant
以生成一个
ZonedDateTime
对象。
ZonedDateTime zdt = instant.atZone( z ) ;
提取时间部分,不包括日期和时区。
LocalTime lt = zdt.toLocalTime() ;
比较。使用 Duration
计算经过的时间。
Duration d = Duration.between( ltStart , ltStop ) ;
请注意,这不是一个公平的比较。一天的长度并非总是24小时,而且并非所有时区的所有时间值都是有效的。例如,在美国进行夏令时换季期间,可能根本没有2点钟。因此,1点到4点可能在某个日期上是3个小时,但在另一个日期上只有2个小时。
关于 java.time
java.time 框架内置于 Java 8 及更高版本中。这些类替代了旧的 遗留 日期时间类,如 java.util.Date
、Calendar
和 SimpleDateFormat
。
Joda-Time项目现在处于维护模式,建议迁移到java.time类。
要了解更多信息,请参见Oracle教程。并在Stack Overflow上搜索许多示例和解释。规范是JSR 310。
您可以直接与数据库交换java.time对象。使用符合JDBC 4.2或更高版本的JDBC驱动程序。无需字符串,无需java.sql.*
类。
如何获取java.time类?
ThreeTen-Extra项目通过增加类来扩展java.time。该项目是java.time可能未来添加的潜在试验场。您可能会在这里找到一些有用的类,例如Interval
, YearWeek
, YearQuarter
以及更多。
Calendar
对象,而只使用Date
成员。 - David R TribbleDate
和Calendar
。更加简单、更加清晰,并且具有正确的时区处理能力。 - Basil Bourque