How to convert from org.joda.time.DateTime to java.time.ZonedDateTime

I have a data source with stored DateTime objects of joda time. I need to convert them to java ZonedDateTime objects while maintaining the original timezone.

It is not enough to keep the offset, as some DateTime objects are daily recurring tasks, and these tasks must be performed at a specific time in a specific time zone for each date. Therefore, they must follow the indicated TimeZone transitions, such as summer and winter. I can’t say the final use of DateTime objects, so I need to keep the time zone information on all objects safe.

How to convert from org.joda.time.DateTime to java.time.ZonedDateTime?

Everything will be

ord.joda.time.DateTimeZone.getId ()

match id available in

java.time.ZoneId

+7
java timezone datetime jodatime java-time
source share
2 answers

Not all Joda-Time timezone lines will correspond to java.time , but the vast majority will be, as they are both based on IANA tz data. Compare DateTimeZone.getAvailableIDs() with ZoneId.getAvailableZoneIds() to determine the mismatch. Additional identifiers can be mapped using ZoneId.of(String, Map) .

To make the basic transformation the most efficient way, you have to go through each field:

 ZonedDateTime zdt = ZonedDateTime.ofLocal( LocalDateTime.of( dt.getYear(), dt.getMonthOfYear(), dt.getDayOfMonth(), dt.getHourOfDay(), dt.getMinuteOfHour(), dt.getSecondOfMinute(), dt.getMillisOfSecond() * 1_000_000), ZoneId.of(dt.getZone().getID(), ZoneId.SHORT_IDS), ZoneOffset.ofTotalSeconds(dt.getZone().getOffset(dt) / 1000)); 

Note the use of ZoneId.SHORT_IDS as a Map in this case.

For a simpler solution that handles most use cases, but at lower performance, use this:

 ZonedDateTime zdt = dt.toGregorianCalendar().toZonedDateTime(); 
+15
source share

You should avoid providing each field separately if you work with daylight saving time. Instead, convert using epochMillis, as in the following example.

 Instant instant = Instant.ofEpochMilli(dt.getMillis()); ZoneId zoneId = ZoneId.of(dt.getZone().getId(), ZoneId.SHORT_IDS); ZonedDateTime zdt = ZonedDateTime.ofInstant(instant, zoneId); 

Otherwise, you will lose one hour on the day of the transition. For example, Germany switched from summer time (GMT + 2) to winter time (GMT + 1) 10/29/2017 at 03:00 GMT + 2, which is 02:00 GMT + 1. On this day, you have 2 copies of 02: 00 - earlier with GMT + 2 and later with GMT + 1.

Since you are working with ZoneIds, not offsets, there is no way to know which of the two instances you want. By default, the first is accepted during conversion. Both 02:00 GMT + 2 and 02:00 GMT + 1 will be converted at 02:00 GMT + 2 if you provide hourOfDay along with ZoneId.

+3
source share

All Articles