从 DataObject (SDO) 获取日期而不丢失小时 (JAVA)

Get Date from a DataObject (SDO) without losing the hour (JAVA)

我正在尝试从作为输入的 DataObject (Service Date Object (SDO)) 中获取日期并将其插入到 Oracle 数据库中。问题是我得到的日期似乎没有介绍的时间。

我正在使用 DataObject 中的 setDate() 方法,其值如下:2019-05-22T13:30:00Z。

出于某种原因,当使用 getDate() 时,返回的是输入的日期,小时设置为 0 (2019-05-22 00:00:00)。

我不确定这是由于输入格式还是与 java.utils 的日期 class 有关的问题。

一个简单的解决方案是将它作为字符串传递并使用某种格式将其转换为日期,但我想保存这个中间步骤。

java.util.Date 对比 java.sql.Date

你的问题没有提供足够的细节来确定,但我可以进行有根据的猜测。

returning is the day entered with the hour set at 0 (2019-05-22 00:00:00).

我怀疑您调用 setDate and/or getDate 的代码使用的是 java.sql.Date 对象而不是 java.util.Date 对象。

检查您的 import 语句。 如果您不小心使用了错误的 class,那将解释 time-of-day 设置为00:00.

  • java.util.Date 表示 UTC 中的时刻(一个日期,一个 time-of-day,一个 offset-from-UTC 为零 hours-minutes-seconds)。
  • java.sql.Date 假装代表date-only,没有time-of-day和时区或offset-from-UTC。实际上 确实 包含 time-of-day 和偏移量,但试图将时间调整为 00:00:00.0 作为伪装的一部分。

令人困惑?是的。 date-time class 早期 Java 中的这些旧 date-time es 是一团糟,由不了解 date-time 处理的复杂性的人构建。 避免这些遗留问题 date-time classes!

这些遗留 classes 在几年前被 JSR 310 中定义的现代 java.time classes 所取代。尝试做所有您在 java.time 中的工作。与尚未针对 java.time 更新的旧代码(例如 SDO)进行互操作时,调用添加到旧 classes.[=57= 的新转换方法]

java.util.Date 的现代替代品是 java.time.Instant。两者都代表 UTC 中的一个时刻,尽管 Instant 具有比毫秒更精细的纳秒分辨率。

Instant instant = Instant.now() ;  // Capture the current moment in UTC.

从现代 class 转换为传统 class。当心 data-loss:小数秒中的任何 microseconds or nanoseconds 都会被截断为毫秒(如上所述)。

java.util.Date d = java.util.Date.from( instant ) ;  // Convert from modern to legacy. Truncates any microseconds or nanoseconds.

传递给您的 SDO 对象。

mySdoDataObject.setDate( d ) ;

换个方向,检索遗留 java.util.Date 对象并立即转换为 Instant

Instant instant = mySdoDataObject.getDate().toInstant() ;  

要查看特定地区(时区)人们使用的 wall-clock 时间的同一时刻,请应用 ZoneId 以获得 ZonedDateTime 对象。

ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;  // Same moment, same point on the timeline, different wall-clock time.

An easy solution would be to pass it as String

没有!使用智能对象,而不是哑字符串。我们在 Java 中内置了 industry-leading date-time 库,所以请使用它。

数据库

从JDBC 4.2开始,我们可以直接与数据库交换java.time对象。

您的 JDBC 驱动程序可以选择处理 Instant。如果不是,则转换为 OffsetDateTime.

OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;
myPreparedStatement.setObject( … , odt ) ;

检索。

OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
Instant instant = odt.toInstant() ;

关于java.time

java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

要了解更多信息,请参阅 Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310

Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

您可以直接与数据库交换 java.time 对象。使用 JDBC driver compliant with JDBC 4.2 或更高版本。不需要字符串,不需要 java.sql.* classes.

从哪里获得java.time classes?

ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.