tl;博士
有没有一种简单的方法可以将 LocalDate(Java 8 引入)转换为 java.util.Date 对象? “简单”是指比这更简单
不。你做得正确,并且尽可能简洁。
java.util.Date.from( // Convert from modern java.time class to troublesome old legacy class. DO NOT DO THIS unless you must, to inter operate with old code not yet updated for java.time.
myLocalDate // `LocalDate` class represents a date-only, without time-of-day and without time zone nor offset-from-UTC.
.atStartOfDay( // Let java.time determine the first moment of the day on that date in that zone. Never assume the day starts at 00:00:00.
ZoneId.of( "America/Montreal" ) // Specify time zone using proper name in `continent/region` format, never 3-4 letter pseudo-zones such as “PST”, “CST”, “IST”.
) // Produce a `ZonedDateTime` object.
.toInstant() // Extract an `Instant` object, a moment always in UTC.
)
阅读下面的问题,然后考虑一下。怎么可能更简单?如果你问我约会从几点开始,除了问你“在哪里?”,我还能怎么回答?新的一天在法国巴黎比在加利福尼亚州蒙特利尔更早,在加尔各答更早,在新西兰奥克兰更早,所有不同的时刻。
因此,在将仅日期 (LocalDate) 转换为日期时间时,我们必须应用时区 (ZoneId) 以获得分区值 (ZonedDateTime),并且然后移动到 UTC (Instant) 以匹配 java.util.Date 的定义。
详情
首先,尽可能避免使用旧的旧日期时间类,例如 java.util.Date。它们设计不佳,令人困惑且麻烦。它们被 java.time 类取代是有原因的,实际上,有许多原因。
但如果必须,您可以将 java.time 类型转换为/从旧类型转换。寻找添加到旧类的新转换方法。
java.util.Date → java.time.LocalDate
请记住,java.util.Date 是用词不当,因为它表示日期加上 UTC 时间。相比之下,LocalDate 类表示没有时间和时区的仅日期值。
从java.util.Date 到java.time 意味着转换到java.time.Instant 的等效类。 Instant 类表示 UTC 时间线上的时刻,分辨率为 nanoseconds(最多九 (9) 位小数)。
Instant instant = myUtilDate.toInstant();
LocalDate 类表示没有时间和时区的仅日期值。
时区对于确定日期至关重要。对于任何给定的时刻,日期在全球范围内因区域而异。例如,Paris France 中午夜过后几分钟是新的一天,而 Montréal Québec 中仍然是“昨天”。
所以我们需要将Instant 移动到一个时区。我们申请ZoneId 以获得ZonedDateTime。
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( z );
从那里,要求一个仅限日期,LocalDate。
LocalDate ld = zdt.toLocalDate();
java.time.LocalDate → java.util.Date
换个方向,从java.time.LocalDate 到java.util.Date 意味着我们要从仅日期到日期时间。所以我们必须指定一个时间。您可能想在一天的第一时间去。 不要假设那是00:00:00。夏令时 (DST) 等异常意味着第一个时刻可能是另一个时间,例如 01:00:00。让 java.time 通过在 LocalDate 上调用 atStartOfDay 来确定该值。
ZonedDateTime zdt = myLocalDate.atStartOfDay( z );
现在提取一个Instant。
Instant instant = zdt.toInstant();
通过调用 from( Instant ) 将 Instant 转换为 java.util.Date。
java.util.Date d = java.util.Date.from( instant );
更多信息
关于java.time
java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.Date、Calendar 和 SimpleDateFormat。
要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310。
Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。
您可以直接与您的数据库交换 java.time 对象。使用符合JDBC 4.2 或更高版本的JDBC driver。不需要字符串,不需要java.sql.* 类。 Hibernate 5 & JPA 2.2 支持 java.time。
从哪里获取 java.time 类?
ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如Interval、YearWeek、YearQuarter 和more。