稍微短一点的方法:
如果您可以使用ZoneOffset 而不是ZoneId,那么代码可能会稍微缩短。
java.time.LocalDateTime java8LDT = java.time.LocalDateTime.now();
org.joda.time.LocalDateTime jodaLDT = new org.joda.time.LocalDateTime(
java8LDT.toInstant(ZoneOffset.UTC).toEpochMilli()
);
通过向toInstant() 方法提供时区偏移量,可以取消对atZone() 方法的调用。
更详细的解释
澄清一下,我删除的步骤是创建中间 ZonedDateTime 对象。这部分序列仍然与 Java 8 API 相关,然后与 Joda 相关。
转换过程首先涉及将 Java 8 LocalDateTime 转换为自纪元以来的毫秒数。这可以通过几种不同的方式来实现。例如在 Andreas 的回答中:
LocalDateTime ldt = LocalDateTime.now();
ZonedDateTime zdt = ldt.atZone(ZoneId.systemDefault());
Instant instant = zdt.toInstant();
long millis = instant.toEpochMilli();
或者我的替代方案:
LocalDateTime ldt = LocalDateTime.now();
Instant instant = ldt.toInstant(ZoneOffset.UTC);
long millis = instant.toEpochMilli();
不同之处在于我跳过了创建 Java 8 ZonedDateTime 而是将时区偏移量传递给 toInstant() 方法。
从这一点上两个答案是相同的。
org.joda.time.LocalDateTime jodaLocalDateTime = new org.joda.time.LocalDateTime(millis);
注意事项
这在使用不适用夏令时更改的一致偏移量进行转换时效果很好。例如,UTC 始终为 +0:00。如果您需要转换为偏移量可以更改的本地时区,那么您将需要使用 atZone() 的稍长的答案
同时具有 API(Java 8 和 Joda)的 LocalDateTime 是没有时区的 DateTime。但是,如果您有自纪元以来的毫秒数,那么您需要一个偏移量来导出日期和时间。 Java 8 API 需要显式传入偏移量或时区,而如果没有传入,Joda API 将使用系统默认值。
构造 Joda LocalDateTime 的更精确方法是:
org.joda.time.LocalDateTime jodaLocalDateTime = new org.joda.time.LocalDateTime(millis, DateTimeZone.UTC);
这只会在构建期间使用时区来获取正确的日期和时间。一旦构造函数完成,时区将不会成为对象的一部分,因为 LocalDateTime 没有时区。