tl;博士
从旧的 java.util.Date 对象开始,更改日期,同时保持 UTC 中的时间。
myJavaUtilDate // Your `java.util.Date` object. Now legacy; avoid!
.toInstant() // Convert fromlegacy class to modern class, `Instant`.
.atOffset( ZoneOffset.UTC ) // Convert from basic building-block class `Instant` to the more flexible class `OffsetDateTime`.
.with( // Move from one date to another.
LocalDate.of( 1900 , Month.JANUARY , 1 ) // Specify date while keeping time-of-day, and keeping the same offset-from-UTC.
) // Returns a second `OffsetDateTime` object, per immutable objects.
您可以使用 JDBC 4.2 或更高版本将生成的 OffsetDateTime 对象传递到您的数据库,而无需 Timestamp,如下所述。
避免使用旧的日期时间类
我被告知时间戳的日期值必须设置为 1900-01-01。
我怀疑你对 deprecated constructor 中的 java.sql.Timestamp 的奇怪之处感到困惑,它从 1900 年开始计算年份。Javadoc 将第一个参数描述为:year - 年份减去 1900。
这将是遗留日期时间类中发现的许多棘手的设计缺陷之一。完全避免这些课程。仅使用 java.time 包中的日期时间类。
Instant 而不是 java.util.Date
如果给定一个java.util.Date 对象,立即转换为它的替换Instant。
Instant instant = myJavaUtilDate.toInstant() ;
如果你必须产生一个java.sql.Timestamp对象时间与尚未更新到java.time的旧代码互操作,你可以转换。
java.sql.Timestamp ts = Timestamp.from( instant ) ;
您不应再使用Timestamp 与数据库交换值。 JDBC 4.2 及更高版本需要支持某些 java.time 类,包括 OffsetDateTime。
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;
myPreparedStatement.setObject( … , odt ) ;
检索。
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
你说:
但现在我必须将日期固定为该特定值,同时保持时间不变。
你把我弄丢了。编辑您的问题以澄清您的问题和期望的结果。如果您指的是上面讨论的 1900 年的怪事,那么如果您使用 java.time 类按照我的代码进行操作,那就没有实际意义了。
如果您确实想要 1900 年 1 月 1 日的日期,同时保留传递的 java.util.Date 中的时间,您必须首先了解 Date 对象代表 UTC 中的时刻。因此,如果通过另一个时区查看同一时刻,则在 UTC 中看到的时间可能会有所不同。
我将继续假设您想要 UTC 中的时间。但是您应该编辑您的问题以澄清 UTC 与某个时区。
LocalDate ld = LocalDate.of( 1900 , Month.JANUARY , 1 ) ;
OffsetDateTime odt = myJavaUtilDate.toInstant().atOffset( ZoneOffset.UTC ).with( ld ) ;