1. Introduction
In this tutorial, we learn about the difference between Date and OffsetDateTime. We also learn how to convert from one to the other.
2. Difference Between Date and OffsetDateTime
OffsetDateTime was introduced in JDK 8 as a modern alternative to java.util.Date.
OffsetDateTime is a thread-safe class that stores date and time to a precision of nanoseconds. Date, on the other hand, is not thread-safe and stores time to millisecond precision.
OffsetDateTime is a value-based class, which means that we need to use equals when comparing references instead of the typical ==.
The output of OffsetDateTime‘s toString method is in ISO-8601 format, while Date‘s toString is in a custom non-standard format.
Let’s call toString on of both classes to see the difference:
Date: Sat Oct 19 17:12:30 2019
OffsetDateTime: 2019-10-19T17:12:30.174Z
Date can’t store timezones and corresponding offsets. The only thing that a Date object contains is the number of milliseconds since 1 January 1970, 00:00:00 UTC, so if our time isn’t in UTC we should store the timezone in a helper class. On the contrary, OffsetDateTime stores the ZoneOffset internally.
3. Converting Date to OffsetDateTime
Converting Date to OffsetDateTime is pretty simple. If our Date is in UTC, we can convert it with a single expression:
Date date = new Date();
OffsetDateTime offsetDateTime = date.toInstant()
.atOffset(ZoneOffset.UTC);
If the original Date isn’t in UTC, we can provide the offset (stored in a helper object, because as mentioned earlier, the Date class can’t store timezones).
Let’s say our original Date is +3:30 (Tehran time):
int hour = 3;
int minute = 30;
OffsetDateTime offsetDateTime = date.toInstant()
.atOffset(ZoneOffset.ofHoursMinutes(hour, minute));
Also, we can use the getTimeZoneOffset() from the Date class to compute the offset in minutes between a local time and UTC:
OffsetDateTime offsetDateTime = date.toInstant()
.atOffset(ZoneOffset.ofTotalSeconds(date.getTimezoneOffset() * -60));
Here, we convert the minutes between the local time and UTC to seconds. The ZoneOffset.ofTotalSeconds() method expects the offset value as the number of seconds to add to the UTC to get the local time. Since the getTimezoneOffset() method returns the opposite (minutes to subtract from local time to get UTC), we multiply by -60 to convert to seconds and reverse the sign.
The Date object doesn’t store any time zone information. However, invoking the getTimezoneOffset() method on a Date object gets the system default timezone at the time the Date object was invoked.
OffsetDateTime provides many useful methods that can be used afterward. For example, we can simply getDayOfWeek(), getDayOfMonth(), and getDayOfYear(). It’s also very easy to compare two OffsetDateTime objects with isAfter and isBefore methods.
Above all, it’s a good practice to avoid the deprecated Date class entirely.
4. Conclusion
In this tutorial, we learned how simple it is to convert from Date to OffsetDateTime.
And, as always, the code is available over on Github.