Date and time in Java – java.util.Date and java.time.Instant
I have lately discovered, I wasn’t fully aware how date and time works in Java. In my current project we are using date and time quite heavily, but until recently we were on Java 7 and we have used java.util.Date and Joda-Time library.
Recently things have changed when we’ve started a new project using Java 8 with brand new and shining Date and Time API (JSR 310). Because we are integrating our application with external system which API library was using old java.util.Date, we had to convert data between old java.util.Date and new date and time Java API.
There are several questions to ask:
What is the equivalent of java.util.Date in Java 8?
Equivalent of java.util.Date in Java 8 is java.time.Instant
How to convert between java.util.Date and java.time.Instant
Date class has new method in Java 8
Date date = new Date();
Instant instant = date.toInstant();
Why java.time.LocalDateTime is not equivalent of java.util.Date? Isn’t LocalDateTime same as DateTime from Joda-Time library?
To answer this question it is necessary to understand what java.util.Date is and how its value is represented. Java.util.Date is simply number of millisecond since EPOCH (1st of January 1970). There is no information about the timezone in it, but it is universal for the whole earth. It is representing point in time. E.g. it is 2015-08-03 7:00 in New York or 2015-08-03 12:00 in London, but it is „1438599600” milliseconds since EPOCH in both locations, in this point of time.
The LocalDateTime from Java 8 which is just informal representation of the Date and Time (e.g. „2015-08-03 3:00”). With LocalDateTime – until you know what timezone it is, it does not precisely determine point in the time.
Joda’s DateTime is a different beast. It has information about the timezone, but if you will not explicitly give timezone when creating it – it will use default system timezone which might be error prone.
So what will happen when I do convert Date to DateTime/LocalDateTime? Should I do it?
To convert Date to DateTime (from Joda) you need to know first what is the timezone of the DateTime you want to receive.
Date date = new Date();
DateTime dateTime = new DateTime(date, DateTimeZone.forID("Poland"));
This code will do the job. If you’ll not specify the second argument for DateTime – it will use whatever is the machine default, which in many cases is not what you want.
Code to convert Date to LocalDateTime (from Java 8) is quite similar to the one above.
Date date = new Date();
LocalDateTime dateTime = LocalDateTime.ofInstant(date.toInstant(), ZoneId.of("US/Pacific"))
The difference here is that in Java 8, LocalDateTime requires the timezone as a parameter. In case of LocalDateTime information about timezone is used to create object, but it is lost after that. There is no DateTime in Java 8. Instead there is ZonedDateTime and timezone parameter is also required if you want to convert Date to ZonedDateTime.
Date date = new Date();
ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant(date.toInstant(), ZoneId.of("US/Pacific"))
In my opinion Java 8 Date-Time library’s API is really well thought out. It enforce the developer to understand how the date and time is represented and by that, it helps to avoid tricky bugs.