java datetime 转换_java-如何将ZonedDateTime转换为Date?

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.

)

尽管上面的代码没有意义。 java.sql.*和java.util.Date都表示UTC中的时刻,始终表示UTC。 上面的代码与以下内容具有相同的作用:

new java.util.Date() // Capture current moment in UTC.

这里使用java.sql.*没有任何好处。如果您已经拥有java.util.Date,请提取Instant以适应UTC。

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.sql.*)转换为旧式java.sql.*对象。 从ZonedDateTime中提取java.util.Date,并将其传递到java.sql.*。

资料遗失

请注意,您将遭受数据丢失的困扰,因为java.sql.*自纪元开始跟踪纳秒,而java.util.Date自纪元以来跟踪毫秒。

d346492007b6104b3bbbb769ec2efcef.png

您的问题和评论提出了其他问题。

使服务器保持UTC状态

通常,最好将您的服务器的主机操作系统设置为UTC。 在我知道的Java实现中,JVM将此主机OS设置作为其默认时区。

指定时区

但是,您永远不应依赖JVM的当前默认时区。 在启动JVM时传递的标志可以设置另一个时区,而不是选择主机设置。 更糟糕的是:任何应用程序任何线程中的任何代码都可以随时调用java.sql.*,以在运行时更改默认值!

卡桑德拉java.sql.*类型

任何体面的数据库和驱动程序都应自动处理调整传递给UTC的日期时间以进行存储。 我不使用Cassandra,但它似乎对日期时间有一些基本的支持。 文档说它的java.sql.*类型是同一时期(UTC 1970年的第一时刻)以来的毫秒数。

ISO 8601

此外,Cassandra接受ISO 8601标准格式的字符串输入。 幸运的是,java.time使用ISO 8601格式作为解析/生成字符串的默认值。 java.sql.*类的java.sql.*实现效果很好。

精度:毫秒vs纳秒级

但是首先,我们需要将ZonedDateTime的纳秒精度降低到毫秒。 一种方法是使用毫秒创建新的Instant。 幸运的是,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.sql.*实例(不要与java.sql.*混淆)。 因此,您可以在上面的代码中使用该java.sql.*创建一个j.u.Date。

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 =即时+ ZoneId

我们只提取UTC中已经存在的Instant部分(基本上在UTC中,请阅读类文档以获取详细信息)。

关于java.time

java.time框架内置于Java 8及更高版本中。 这些类取代了麻烦的旧的传统日期时间类,例如java.sql.*、java.sql.*和java.sql.*。

现在处于维护模式的Joda-Time项目建议迁移到java.time类。

要了解更多信息,请参阅Oracle教程。 并搜索Stack Overflow以获取许多示例和解释。 规范是JSR 310。

您可以直接与数据库交换java.time对象。 使用与JDBC 4.2或更高版本兼容的JDBC驱动程序。 不需要字符串,也不需要java.sql.*类。

从哪里获取java.time类?

Java SE 8,Java SE 9,Java SE 10和更高版本内置。

带有捆绑实现的标准Java API的一部分。

Java 9增加了一些小功能和修复。

Java SE 6和Java SE 7许多java.time功能都被反向移植到ThreeTen-Backport中的Java 6和7。

Android的更高版本的Android捆绑java.time类的实现。

对于早期的Android(<26),ThreeTenABP项目采用ThreeTen-Backport(如上所述)。 请参见如何使用ThreeTenABP ....

ThreeTen-Extra项目使用其他类扩展了java.time。 该项目为将来可能向java.time添加内容提供了一个试验场。 您可能会在这里找到一些有用的类,例如YearQuarter、YearQuarter、YearQuarter等。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值