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.
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.
So the short answer to your question is: YES (deprecated).
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.
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 .
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.
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);
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());
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With