tl;博士
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 中的一个时刻。确定日期和时间需要 time zone 。对于任何给定的时刻,日期和时间在全球范围内因区域而异。例如,Paris France 中午夜后几分钟是新的一天,而 Montréal Québec 中仍然是“昨天”。
如果没有指定时区,JVM 会隐式应用其当前的默认时区。该默认值可能在运行时(!)期间change at any moment,因此您的结果可能会有所不同。最好将 desired/expected time zone 明确指定为参数。
以continent/region 的格式指定proper time zone name,例如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 及更高版本中。这些类取代了麻烦的旧 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。