tl;博士
LocalDateTime.now(
ZoneId.of( "America/Montreal" )
)
.toString()
2018-01-23T12:34:56.123456
如果要删除分钟和秒,请截断。
LocalDateTime.now(
ZoneId.of( "America/Montreal" )
)
.truncatedTo( ChronoUnit.HOURS )
.toString()
2018-01-23T12:00:00
详情
Calendar 类现在是遗留的,被现代的 java.time 类所取代。此外,Calendar 始终带有时区,因此无法满足您的需求。
在java.time 中,以“Local...”命名的三个类故意缺少任何时区或与UTC 偏移的概念。 local 一词表示任何 地区或每个 地区,而不是特定地区。
仅日期值,缺少时间和时区。
时间值,缺少日期和时区。仅限于一个 24 小时周期。
带有时间的日期,缺少时区。
不代表片刻吗,不是时间线上的一个点。表示大约 26-27 小时范围内的潜在时刻(不同时区使用的不同偏移量)。 LocalDateTime 没有实际意义,直到您应用时区或与 UTC 的偏移量来确定特定时刻。
当前时刻
使用Instant 类捕捉UTC 中的当前时刻。此类使用纳秒级的分辨率,但当前时刻可能不是那么精细,这取决于您的 JVM 实现、主机操作系统和主机计算机硬件时钟的限制。
Instant instant = Instant.now() ; // Capture current moment in UTC.
如果您想通过特定地区的人们使用的点击墙壁时间的镜头来查看当前时刻,请应用时区。申请ZoneId 以获得ZonedDateTime。
ZoneId z = ZoneId.of( "Pacific/Auckland" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
要仅使用 ZonedDateTime 中的日期和时间,但放弃时区,请生成 LocalDateTime 对象。
LocalDateTime ldt = zdt.toLocalDateTime() ; // Extract the date and time-of-day but omit the time zone.
作为快捷方式,您可以跳过分区对象Instant 和ZonedDateTime。您仍然需要一个时区,ZoneId,因为对于任何给定的时刻,日期和时间在全球各地都因时区而异。 ZoneId 用于确定在该地区人们使用的挂钟时间中看到的当前时刻。一旦被捕获,ZoneId 就会被生成的LocalDateTime 对象遗忘。如果您想保留该区域,请记住该区域,您将使用 ZonedDateTime 而不是 LocalDateTime。
LocalDateTime ldt = LocalDateTime.now( z ) ;
如果您想要 JVM 在运行时的当前默认时区,请将调用返回的 ZoneId 传递给 ZoneId.systemDefault。请注意,该 JVM 中任何应用程序的任何线程中的任何代码都可以随时更改默认值。
如果您想要 UTC 而不是某个时区,请传递来自 ZoneId、ZoneOffset.UTC 的 ZoneOffset 子类的常量。
LocalDateTime.now( ZoneOffset.UTC ) // Capture the current date and time of day as seen in UTC (an offset of zero), and then discard that offset/zone info.
关于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。