tl;博士
java.util.Date.from( // Transfer the moment in UTC, truncating any microseconds or nanoseconds to milliseconds.
Instant.now() ; // Capture current moment in UTC, with resolution as fine as nanoseconds.
)
虽然上面的代码中没有意义。两者都表示 UTC 中的某个时刻,始终以 UTC 为单位。上面的代码具有相同的效果:java.util.Date
Instant
new java.util.Date() // Capture current moment in UTC.
此处使用 没有好处。如果已有 ,请通过提取 .ZonedDateTime
ZonedDateTime
Instant
java.util.Date.from( // Truncates any micros/nanos.
myZonedDateTime.toInstant() // Adjust to UTC. Same moment, same point on the timeline, different wall-clock time.
)
其他正确答案
ssoltanid的答案正确地解决了您的具体问题,如何将新派java.time对象()转换为旧派java.util.Date
对象。从 ZonedDateTime 中提取 ,并传递到 java.util.Date.from()
。ZonedDateTime
Instant
数据丢失
请注意,您将遭受数据丢失,因为自纪元以来跟踪纳秒,而自纪元以来跟踪毫秒。Instant
java.util.Date
您的问题和意见会引发其他问题。
将服务器保持在 UTC 格式
通常,您的服务器应将其主机操作系统设置为 UTC 作为最佳做法。JVM 在 I 所知道的 Java 实现中将此主机操作系统设置作为其默认时区。
指定时区
但是,您永远不应该依赖 JVM 的当前默认时区。启动 JVM 时传递的标志可以设置另一个时区,而不是选择主机设置。更糟糕的是:任何应用程序的任何线程中的任何代码在任何时候都可以调用java.util.TimeZone::setDefault
以在运行时更改默认值!
卡桑德拉型Timestamp
任何像样的数据库和驱动程序都应该自动处理将传递的日期时间调整为UTC以进行存储。我不使用Cassandra,但它似乎确实对日期时间有一些基本的支持。文档说它的时间戳
类型是来自同一纪元(UTC中1970年的第一个时刻)的毫秒数。
国际标准化组织 ISO 8601
此外,Cassandra 接受 ISO 8601 标准格式的字符串输入。幸运的是,java.time使用ISO 8601格式作为其解析/生成字符串的默认值。Instant
类的toString
实现会做得很好。
精度:毫秒与纳秒
但首先,我们需要将 ZonedDateTime 的纳秒精度降低到毫秒。一种方法是使用毫秒创建一个新的即时。幸运的是,java.time有一些方便的方法来转换到毫秒和从毫秒转换。
示例代码
下面是 Java 8 Update 60 中的一些示例代码。
ZonedDateTime zdt = ZonedDateTime.now( ZoneId.of( "America/Montreal" ) );
…
Instant instant = zdt.toInstant();
Instant instantTruncatedToMilliseconds = Instant.ofEpochMilli( instant.toEpochMilli() );
String fodderForCassandra = instantTruncatedToMilliseconds.toString(); // Example: 2015-08-18T06:36:40.321Z
或者根据此Cassandra Java驱动程序文档,您可以传递java.util.Date
实例(不要与java.sqlDate
混淆)。因此,您可以在上面的代码中从中制作一个j.u.Date。instantTruncatedToMilliseconds
java.util.Date dateForCassandra = java.util.Date.from( instantTruncatedToMilliseconds );
如果经常这样做,你可以做一个单行。
java.util.Date dateForCassandra = java.util.Date.from( zdt.toInstant() );
但是创建一个小小的实用方法会更整洁。
static public java.util.Date toJavaUtilDateFromZonedDateTime ( ZonedDateTime zdt ) {
Instant instant = zdt.toInstant();
// Data-loss, going from nanosecond resolution to milliseconds.
java.util.Date utilDate = java.util.Date.from( instant ) ;
return utilDate;
}
请注意所有这些代码与问题中的区别。问题的代码正在尝试将 ZonedDateTime 实例的时区调整为 UTC。但这不是必要的。概念:
ZonedDateTime = Instant + ZoneId
我们只是提取即时部分,该部分已经在UTC中(基本上是在UTC中,请阅读类文档以获取确切的详细信息)。
关于 java.time
java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧旧日期时间类,如java.util.Date
,Calendar
和SimpleDateFormat
。
Joda-Time 项目现在处于维护模式,建议迁移到 java.time 类。
要了解更多信息,请参阅 Oracle 教程。搜索 Stack Overflow 以获取许多示例和解释。规格是JSR 310。
您可以直接与数据库交换 java.time 对象。使用符合 JDBC 4.2 或更高版本的 JDBC 驱动程序。不需要字符串,不需要类。java.sql.*
从哪里获取 java.time 类?
ThreeTen-Extra 项目通过其他类扩展了 java.time。这个项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如Interval
,YearWeek
,YearQuarter
等。