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.
您可以OffsetDateTime
使用 JDBC 4.2 或更高版本将生成的对象传递给您的数据库,而无需Timestamp
如下所述。
避免遗留的日期时间类
我被告知时间戳日期的值必须设置为 1900-01-01。
我怀疑您对从 1900 年开始计算年份的已弃用构造函数中的奇怪之处感到困惑java.sql.Timestamp
。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 ) ;