That seems to be the general way of doing such conversion.
As the classes from both API's are not interoperable with each other (you can't use Joda's DateTime
with Java Time's DateTimeFormatter
and so on), the common factor between them seems to be the long
epochMilli value.
So I see no better way than creating a java.time.Instant
and then converting it to OffsetDateTime
using the timezone from Joda's object.
Well, I think there's one thing that can be slightly improved. This code:
jodaDateTime.getZone().toTimeZone().toZoneId()
The toTimeZone()
method creates a java.util.Timezone
instance, which is used to create a java.time.ZoneId
via toZoneId()
method.
You can avoid the creation of this temporary TimeZone
object by doing:
ZoneId.of(jodaDateTime.getZone().getID())
This code doesn't create the temporary TimeZone
object, and creates the ZoneId
directly. As Joda's DateTimeZone
doesn't work with short IDs (like IST
or PST
), we can assume that the ID will be recognizable by ZoneId
class (as it also works with long ID names, such as Europe/London
). It also works if the Joda's DateTimeZone
ID is an offset (such as +01:00
).
Not sure if avoiding the creation of one temporary object is cleaner enough, but anyway it's an improvement (a tiny one, but it still is).
So, the final code will be very similar to yours, with only the change proposed above:
// java.time.Instant
Instant instant = Instant.ofEpochMilli(jodaDateTime.getMillis());
// create the OffsetDateTime
OffsetDateTime.ofInstant(instant, ZoneId.of(jodaDateTime.getZone().getID()));
There's another alternative (very similiar, but not sure if cleaner): get the total offset (instead of the timezone) and use it to create a java.time.ZoneOffset
:
long millis = jodaDateTime.getMillis();
// java.time.Instant
Instant instant = Instant.ofEpochMilli(millis);
// get total offset (joda returns milliseconds, java.time takes seconds)
int offsetSeconds = jodaDateTime.getZone().getOffset(millis) / 1000;
OffsetDateTime.ofInstant(instant, ZoneOffset.ofTotalSeconds(offsetSeconds));
You can also use the suggestion made by @assylias' comment, but I'm not sure if formatting to a String
and then parsing it to OffsetDateTime
is cleaner than this (although it also works).