Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java 8 ZonedDateTime or OffsetDateTime to replace Joda DateTime

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.

like image 939
ttt Avatar asked Jan 05 '16 10:01

ttt


People also ask

Should I use OffsetDateTime or ZonedDateTime?

Use OffsetDateTime to store unique instants in the universal timelines irrespective of the timezones, such as keeping the timestamps in the database or transferring information to remote systems worldwide. Use ZonedDateTime for displaying timestamps to users according to their local timezone rules and offsets.

Is Joda DateTime deprecated?

So the short answer to your question is: YES (deprecated).

What is the difference between LocalDateTime and ZonedDateTime?

LocalDateTime – same as LocalDate, but includes time with nanosecond precision. OffsetDateTime – same as LocalDateTime, but with time zone offset. LocalTime – time with nanosecond precision and without date information. ZonedDateTime – same as OffsetDateTime, but includes a time zone ID.

What is OffsetDateTime in Java?

OffsetDateTime is an immutable representation of a date-time with an offset. This class stores all date and time fields, to a precision of nanoseconds, as well as the offset from UTC/Greenwich. For example, the value "2nd October 2007 at 13:45.30. 123456789 +02:00" can be stored in an OffsetDateTime .


3 Answers

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.

like image 144
spa Avatar answered Oct 20 '22 02:10

spa


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);
like image 6
Mateusz Sroka Avatar answered Oct 20 '22 01:10

Mateusz Sroka


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());
    
like image 2
assylias Avatar answered Oct 20 '22 03:10

assylias