Reputation: 7733
On an Android device (7.0), there is this crash:
Fatal Exception: org.joda.time.IllegalInstantException: Illegal instant due to time zone offset transition (daylight savings time 'gap'): 1977-05-01T00:00:00.000 (Africa/Casablanca)
at org.joda.time.chrono.ZonedChronology.localToUTC(ZonedChronology.java:157)
at org.joda.time.chrono.ZonedChronology.getDateTimeMillis(ZonedChronology.java:122)
at org.joda.time.chrono.AssembledChronology.getDateTimeMillis(AssembledChronology.java:133)
at org.joda.time.base.BaseDateTime.<init>(BaseDateTime.java:257)
at org.joda.time.base.BaseDateTime.<init>(BaseDateTime.java:198)
at org.joda.time.DateTime.<init>(DateTime.java:323)
It appears when the timezone is: Africa/Casablanca (= GMT 0)
My code:
// Failed:
DateTime dateTime = new DateTime(year, month, 1);
// Failed
DateTime dateTime = new DateTime(year, month, 1, 0, 0, 0, 0,
DateTimeZone.forID(TimeZone.getDefault().getID()));
// Failed
DateTime dateTime = new DateTime(year, month, 1, 0, 0, 0,
DateTimeZone.forTimeZone(TimeZone.getDefault()));
I can't understand why it's failed with this timezone. If I use another timezone (like GMT+1) there is no problem at all.
Upvotes: 1
Views: 1548
Reputation: 23
That's because in May 1st 1977, Casablanca switched to Daylight Saving Time: https://www.timeanddate.com/time/zone/morocco/casablanca?year=1977
At midnight, clocks were set 1 hour forward to 1 AM. It's like it "jumped" from 11:59:59 PM directly to 1 AM, so midnight doesn't exist in that timezone, at that date. That's called a gap (or a DST gap, if you prefer).
Joda-Time interprets this as an invalid value at the timezone you're working on, hence the exception.
If you don't want the exception, you can check first if the local date and time is valid at that timezone:
LocalDateTime ld = new LocalDateTime(1977, 5, 1, 0, 0, 0, 0);
DateTimeZone zone = DateTimeZone.forID("Africa/Casablanca");
System.out.println(zone.isLocalDateTimeGap(ld)); // true
// if it's not a gap (isLocalDateTimeGap is false), it's safe to create DateTime
DateTime d = ld.toDateTime(zone);
In this case, it prints true
, because May 1st 1977 at midnight is a gap in Casablanca's timezone, so creating a DateTime
for these values will throw an exception.
It doesn't happen at another timezones because they have different DST rules and the date and time are valid for them.
Upvotes: 2