tl;博士
myJavaUtilDate // The terrible `java.util.Date` class is now legacy. Use *java.time* instead.
.toInstant() // Convert this moment in UTC from the legacy class `Date` to the modern class `Instant`.
.atZone( ZoneId.of( "Africa/Tunis" ) ) // Adjust from UTC to the wall-clock time used by the people of a particular region (a time zone).
.toLocalDate() // Extract the date-only portion.
.atStartOfDay( ZoneId.of( "Africa/Tunis" ) ) // Determine the first moment of that date in that zone. The day does *not* always start at 00:00:00.
java.time
您正在使用可怕的旧日期时间类,这些类在几年前被JSR 310 中定义的现代java.time类所取代。
Date
➙Instant
Ajava.util.Date
代表 UTC 中的时刻。它的替代品是Instant
. 调用添加到旧类的新转换方法。
Instant instant = myJavaUtilDate.toInstant() ;
时区
指定您希望新的一天中的时间有意义的时区。
以、或等格式指定适当的时区名称。永远不要使用 2-4 个字母的缩写,例如或因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。Continent/Region
America/Montreal
Africa/Casablanca
Pacific/Auckland
EST
IST
ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime
将 应用于ZoneId
以Instant
获得ZonedDateTime
. 同一时刻,时间轴上的同一点,但挂钟时间不同。
ZonedDateTime zdt = instant.atZone( z ) ;
改变时间
您要求更改时间。应用 aLocalTime
更改所有时间部分:小时、分钟、秒、小数秒。实例化一个新ZonedDateTime
的,其值基于原始值。java.time类使用这种不可变对象模式来提供线程安全。
LocalTime lt = LocalTime.of( 15 , 30 ) ; // 3:30 PM.
ZonedDateTime zdtAtThreeThirty = zdt.with( lt ) ;
一天的第一刻
但你特地要求 00:00。所以显然你想要一天的第一刻。请注意:某些区域的某些日子并非从 00:00:00 开始。由于夏令时 (DST) 等异常情况,它们可能会在 01:00:00 等其他时间开始。
让java.time确定第一个时刻。提取仅日期部分。然后通过时区获得第一刻。
LocalDate ld = zdt.toLocalDate() ;
ZonedDateTime zdtFirstMomentOfDay = ld.atStartOfDay( z ) ;
调整为 UTC
如果您需要返回 UTC,请提取Instant
.
Instant instant = zdtFirstMomentOfDay.toInstant() ;
Instant
➙Date
如果您需要java.util.Date
与尚未更新为java.time的旧代码进行互操作,请转换。
java.util.Date d = java.util.Date.from( instant ) ;