简体   繁体   中英

Converting java.sql.Timestamp to Instant Time

From my database i retrieve value as :

20-DEC-17 10.15.53.000000000 AM

I want above java.sql.Timestamp to be converted to Instant time as :

2017-12-20T10:15:53Z

I tried following with current time stamp

Timestamp ts2 = new Timestamp(date1.getTime());
Date tradeDate1=new Date(ts2.getTime());
Instant tradeInstant = tradeDate1.toInstant();
System.out.println("Tade Instant"+ tradeInstant);
  • Actual time stamp: Fri Jun 22 16:07:35 IST 2018
  • What is prints in instan : Tade Instant2018-06-22T10:37:35.420Z

The hours/mins/seconds are updated which I dont want - is there a way this can be retained as is?

I am assuming that you are using at least Java 8 and at least JDBC 4.2. I am further assuming that the timestamp doesn't have time zone or offset information in the database, but is to be understood as a timestamp in UTC (which is a recommended practice). In this case I would consider it safest to add the information about UTC offset explicitly in Java:

PreparedStatement yourPreparedStatement 
            = yourConnection.prepareStatement("select trade_timestamp from your_table");
ResultSet rs = yourPreparedStatement.executeQuery();
while (rs.next()) {
    LocalDateTime tradeDateTime = rs.getObject(1, LocalDateTime.class);
    Instant tradeInstant = tradeDateTime.atOffset(ZoneOffset.UTC).toInstant();
    System.out.println("Trade Instant: " + tradeInstant);
}

Note that the code avoids the outdated Timestamp class completely. A LocalDateTime is a date and time of day without time zone or offset. If your database datatype had been timestamp with time zone , you could have passed either Instant.class or OffsetDateTime.class to rs.getObject and have got an Instant or an OffsetDateTime back. JDBC 4.2 only specifies support for OffsetDateTime , but many drivers support Instant too. Obviously with Instant you need no further conversion. With OffsetDateTime do

    Instant tradeInstant = tradeDateTime.toInstant();

Depending on your database and its capabilities it is also possible that you can set UTC as offset/time zone on the database session so you can get the correct instant even from timestamp without time zone.

Discussion: Arvind Kumar Avinash in a comment recommends that one should rely only on the types officially supported by JDBC 4.2, that is, LocalDateTime and OffsetDateTime for our purposes. The types are mentioned at the bottom of the article Why do we need a new date and time library? on Oracle's web site, there's a link at the bottom. Arvind Kumar Avinash further refers us to PSQLException: Can't infer the SQL type to use for an instance of java.time.Instant , also linked to at the bottom. Since comments are fragile, I wanted to include the essence here in the answer.

What went wrong in your code?

It seems your database session understood the timestamp as a date and time in your local time zone (IST, I assume it's for India Standard Time (other interpretations exist)). According to Mark Rotteveel's informative comment this behaviour is required by JDBC, but it doesn't agree with your need when the value is in UTC. Therefore it gave you the wrong point in time, though it looked right when you printed it. The conversion in itself was correct.

Links

Building from the comment about not using SimpleDateFormat, I have moved to DateTimeFormatter:

Date today = new Date();

DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss") // same format
        .withLocale(Locale.UK) // UK locale
        .withZone(ZoneId.systemDefault());

String output = dateTimeFormatter.format( today.toInstant() );

System.out.println( output );

Running gives you:

2018-06-22T14:14:26

I have created a SimpleDateFormat, which only prints "up to seconds":

/* simple date format */   
DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");

/* get toInstant() and convert to date */
Date myDate = Date.from(today.toInstant());

/* myDate formatted using DATE_FORMAT */
String formattedDate = DATE_FORMAT.format(myDate);

System.out.println(formattedDate);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM