1

So I have a date value I had to convert to a timestamp in order to pass the value to a specific method. However, in order to finish the work, I've been told the value of the timestamp's date has to be set to 1900-01-01.

So something like this

        Date startDate = timesDate.getStartDate(); 
        Timestamp startTime = new Timestamp(startDate.getTime());

But now I have to fix the date to that specific value, while keeping the time what it was.

EDIT - I have to pull data from a field that contains a string with a set time.

This will be a start time for one field and an end time for another. When this is saved the string needs to be converted into a timestamp, and the value of the timestamp need to be prefaced with 1900-01-01 alongside the time value.

CAN I ANSWER MY OWN QUESTION?

Jack Parker
  • 547
  • 2
  • 9
  • 32

3 Answers3

2

Here is a start. You should be using LocalDate and LocalDateTime. This is just one way to do it. There may be others that better suit your requirements.

// your epoch
LocalDate ld =  LocalDate.of(1900,1,1);
System.out.println(ld);

// now tag on the time
LocalDateTime ldt = LocalDateTime.of(ld, LocalTime.of(2,3)); // 2:03
System.out.println(ldt);

Prints

1900-01-01
1900-01-01T02:03

To tag on the current time, just do this.

LocalDateTime ldt = LocalDateTime.of(ld, LocalTime.now());
System.out.println(ldt);

Prints

1900-01-01T16:06:50.190778200

You will need to check out the DateTimeFormatter to format the timestamp for your applicaton. For more information on the latest time capabilities check out the java.time package.

WJS
  • 36,363
  • 4
  • 24
  • 39
2

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 ) ;
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
0

so, you want the date portion to be 1900-01-01 but the time portion to be whatever the time is from the timesDate.getStartDate()

Did you try using the Date.set*() methods to set the Year, Month, and Day to the correct values before constructing a new timestamp?

Of course, a lot of the Date methods are deprecated in favor of the Calendar methods, so a cleaner way might be to convert the Date to a Calendar object first ... or just live with the warnings for now.

PaulProgrammer
  • 16,175
  • 4
  • 39
  • 56
  • That is exactly what I want, and I didn't do date.set for each, as I thought it would look sloppy, and thought I'd check if there was something I'm missing. – Jack Parker Jun 08 '20 at 19:45
  • Anything else is even worse. Create a date at `1900-01-01 00:00:00` and then run through `set*` methods to copy over each time part? Works > elegant. You can always make it more elegant later if you think of something better. – PaulProgrammer Jun 08 '20 at 19:56