tl;dr
Starting with a legacy java.util.Date
object, change the date while keeping the time-of-day as seen in 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.
You can pass the resulting OffsetDateTime
object to your database using JDBC 4.2 or later, with no need for Timestamp
as explained below.
Avoid legacy date-time classes
I've been told the value of the timestamp's date has to be set to 1900-01-01.
I suspect you are confused about the oddity in the deprecated constructor for java.sql.Timestamp
that counts year from 1900. The Javadoc describes the first argument as: year
- the year minus 1900.
That would be one of the many screwy design flaws found in the legacy date-time classes. Avoid these classes entirely. Use only date-time classes from the java.time packages.
Instant
instead of java.util.Date
If given a java.util.Date
object, immediately convert to its replacement Instant
.
Instant instant = myJavaUtilDate.toInstant() ;
If you must produce a java.sql.Timestamp
object time interoperate with old code not yet updated to java.time, you can convert.
java.sql.Timestamp ts = Timestamp.from( instant ) ;
You should no longer be using Timestamp
to exchange values with a database. JDBC 4.2 and later requires support for some of the java.time classes including OffsetDateTime
.
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;
myPreparedStatement.setObject( … , odt ) ;
Retrieval.
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
You said:
But now I have to fix the date to that specific value, while keeping the time what it was.
You lost me there. Edit your Question to clarify your problem and desired outcome. If you are referring the 1900 oddity discussed above, that is moot, a non-issue, if you follow my code using the java.time classes.
If you really want the date of January 1st 1900 while keeping the time of day found in the passed java.util.Date
, you must first understand that the Date
object represents a moment in UTC. So the time of day seen in UTC may be differ if viewing that same moment through another time zone.
I will continue assuming you want the time of day as seen in UTC. But you should edit your Question to clarify UTC versus some time zone.
LocalDate ld = LocalDate.of( 1900 , Month.JANUARY , 1 ) ;
OffsetDateTime odt = myJavaUtilDate.toInstant().atOffset( ZoneOffset.UTC ).with( ld ) ;