还有更正确的方法吗?
是的,有。
LocalDate.now(
ZoneId.of( "America/Montreal" )
).atStartOfDay(
ZoneId.of( "America/Montreal" )
)
java.time
Java 8 及更高版本现在内置了新的 java.time 框架。见Tutorial。受 Joda-Time 启发,由 JSR 310 定义,并由 ThreeTen-Extra 项目扩展。
示例
下面是一些示例,使用 java.time。请注意他们如何指定时区。如果省略,则为您的 JVM 当前的默认时区。该默认值可能会有所不同,甚至会在运行时随时更改,因此我建议您明确指定时区,而不是隐式依赖默认值。
这是一个仅日期的示例,没有时间和时区。
ZoneId zonedId = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( zonedId );
System.out.println( "today : " + today );
今天:2015-10-19
这是获取当前日期时间的示例。
ZoneId zonedId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.now( zonedId );
System.out.println( "zdt : " + zdt );
运行时:
zdt : 2015-10-19T18:07:02.910-04:00[美国/蒙特利尔]
一天的第一刻
问题要求时间设置为零的日期时间。这假设一天中的第一时刻始终是时间00:00:00.0,但情况并非总是如此。夏令时 (DST) 和其他异常可能意味着一天可能会在不同的时间开始,例如 01:00.0。
幸运的是,java.time 可以确定一天中适合特定时区的第一个时刻LocalDate::atStartOfDay。让我们看看上面代码中使用名为today 的LocalDate 和名为zoneId 的ZoneId 的一些代码。
ZonedDateTime todayStart = today.atStartOfDay( zoneId );
zdt : 2015-10-19T00:00:00-04:00[美国/蒙特利尔]
互操作性
如果您必须有一个 java.util.Date 用于尚未更新的类以使用 java.time 类型,请转换。调用java.util.Date.from( Instant instant ) 方法。
java.util.Date date = java.util.Date.from( zdt.toInstant() );
关于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。