orb360
orb360

Reputation: 155

Why does this Calendar fail?

So I have a Java app that respects your timezone and I noticed some timezones have invalid dates...

I'm using SimpleDateFormatter('yyyyMMdd') to do the parsing... and found that it fails with a ParseException on certain timezone-date combos.

I looked into the internals and it looks like it's failing because the Calendar class is throwing an IllegalArgumentException.

I'm using setLenient(false) because I don't want the parsing making assumptions. The default using setLenient(true) assumes the missing fields and does not throw the IllegalArgumentException.

Why does this one work:

 public void testCalendarPass() {
    Calendar cal = Calendar.getInstance();
    cal.clear();
    cal.setLenient(false);
    cal.set(Calendar.YEAR, 1995);
    cal.set(Calendar.MONTH, Calendar.JANUARY);
    cal.set(Calendar.DAY_OF_MONTH,1);

    //This call will pass
    cal.getTime();
}

While this one in Pacific/Kiritimati fails:

public void testCalendarFailure() {
    Calendar cal = Calendar.getInstance();
    cal.clear();
    cal.setTimeZone(TimeZone.getTimeZone("Pacific/Kiritimati"));
    cal.setLenient(false);
    cal.set(Calendar.YEAR, 1995);
    cal.set(Calendar.MONTH, Calendar.JANUARY);
    cal.set(Calendar.DAY_OF_MONTH,1);

    //This call will fail
    cal.getTime();
}

Does January 1, 1995 not exist in Kiritimati? How do they reference time that falls within that gap?

For now, when I encounter the ParseException I default to the server's timezone for parsing. But this introduces an offset of up to 24 hours (depending on the timezone).

Here's a list of other dates that fail on other timezones:

19930820 FAILS on Kwajalein
19930820 FAILS on Pacific/Kwajalein
20111230 FAILS on MIT
20111230 FAILS on Pacific/Apia
19950101 FAILS on Pacific/Enderbury
20111230 FAILS on Pacific/Fakaofo
19950101 FAILS on Pacific/Kiritimati

Upvotes: 4

Views: 186

Answers (2)

developerwjk
developerwjk

Reputation: 8659

EDIT: I initially thought that Java didn't recognize the meaning of "Pacific/Kiritimati." But it turns out it does. To get a list of all the strings Java will recognize, use:

Set<String> ids = new TreeSet<String>();
for (String id : TimeZone.getAvailableIDs())
   ids.add(id);
for (String id : ids)
  System.out.println(id);

Upvotes: 0

Claudiu
Claudiu

Reputation: 1489

It is because the Kirimati suffered a 24 hours shift on Jan 1st. The Republic of Kiribati, in the Central Pacific, introduced a change of date for its eastern half on 1 January 1995, from time zones UTC−11 and UTC−10 to UTC+13 and UTC+14. Before this, the country was divided by the IDL. After the change, the IDL in effect moved eastwards to go around this country. http://en.wikipedia.org/wiki/International_Date_Line#Eastern_Kiribati.

Also, I took a look at Apia and it seems that: At 0000 local 30 December 2011 the clocks were moved 24 hours ahead http://en.wikipedia.org/wiki/Apia.

So apparently these 2 dates do not actually exist in calendar in the respective timezones because of the 24h shifts. It might be true for all the others.

Upvotes: 1

Related Questions