10

Before Java8, I used Joda's DateTime class to include timezone information and I can easily to convert between DateTime and sql Timestamp.

Once migrate to Java8, which class I should replace? OffsetDateTime or ZonedDateTime?

Also, I tried to use OffsetDateTime, but it seems can't construct back to OffsetDateTime from a sql Timestamp.

For Joda DateTime and Timestamp converter, the code is like:

val joda = DateTime.now()
val sqlJoda = new Timestamp(joda.getMillis)
val jodaBack = new DateTime(sqlJoda)

But for Java8,

val java8 = OffsetDateTime.now()
val sqlJava8 = new Timestamp(java8.toInstant.toEpochMilli)
val java8Back = ???

Anyone has some idea about that? It seems Joda DateTime is really good.

ttt
  • 3,934
  • 8
  • 46
  • 85

3 Answers3

6

Using the Java 8 API in java.time you could do the following:

long ms_since_epoch = 1_500_000_000_000L;
Instant instant = Instant.ofEpochMilli(ms_since_epoch);

// convert milliseconds in UTC to date
OffsetDateTime dateUTC = OffsetDateTime.ofInstant(instant, ZoneOffset.UTC);

Using your convention:

val java8 = OffsetDateTime.now()
val sqlJava8 = new Timestamp(java8.toInstant.toEpochMilli)
val java8Back = OffsetDateTime.ofInstant(sqlJava8.toInstant(), ZoneOffset.UTC);
Mateusz Sroka
  • 2,255
  • 2
  • 17
  • 19
4

You can use ZonedDateTime. Here's some sample code I use to convert to Timestamp back and forth.

public ZonedDateTime from(Timestamp timestamp) {
    if (timestamp == null) {
        return null;
    }
    final ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant(timestamp.toInstant(), ZoneId.of("UTC"));
    return zonedDateTime;
}

public Timestamp to(ZonedDateTime zonedDateTime) {
    if (zonedDateTime == null) {
        return null;
    }
    final Timestamp timestamp = Timestamp.valueOf(zonedDateTime.withZoneSameInstant(ZoneId.of("UTC")).toLocalDateTime());
    return timestamp;
}

Please note that I store date times in the database in UTC.

spa
  • 5,059
  • 1
  • 35
  • 59
  • 2
    The official mapping of a SQL timestamp is either LocalDateTime (timestamp without time zone) or OffsetDateTime (timestamp with timezone). See for example the Maintenance release 2 of JDBC 4 JCP here: https://jcp.org/en/jsr/detail?id=221 – assylias Jan 05 '16 at 11:34
  • Didn't know that. Thanks. Is there any doc out there? – spa Jan 05 '16 at 11:36
3

I assume that your database type is a timestamp with time zone. If it is a timestamp without timezone you will need a different type / conversion mechanism.

The JDBC 4.2 spec recommends to map a timestamp with time zone to an OffsetDateTime. Here is how you can convert between an OffsetDateTime and a java.sql.Timestamp.

  • From OffsetDateTime to Timestamp:

    Timestamp ts = ...;
    OffsetDateTime odt = OffsetDateTime.ofInstant(ts.toInstant(), ZoneId.systemDefault());
    
  • From Timestamp to OffsetDateTime:

    OffsetDateTime odt = ...;
    Timestamp ts = Timestamp.from(odt.toInstant());
    
assylias
  • 321,522
  • 82
  • 660
  • 783