4

所以我有一个尊重你的时区的Java应用程序,我注意到一些时区的日期无效......

SimpleDateFormatter('yyyyMMdd')用来进行解析......并发现它ParseException在某些时区日期组合中失败。

我查看了内部结构,看起来它失败了,因为Calendar班级正在抛出IllegalArgumentException.

我正在使用setLenient(false),因为我不希望解析做出假设。默认使用setLenient(true)假定缺少字段并且不抛出IllegalArgumentException.

为什么这个工作:

 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();
}

虽然太平洋/基里蒂马蒂的这个失败了:

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();
}

1995 年 1 月 1 日在 Kiritimati 中不存在吗?他们如何参考落入该差距的时间?

目前,当我遇到ParseException我默认使用服务器的时区进行解析时。但这会引入长达 24 小时的偏移量(取决于时区)。

以下是在其他时区失败的其他日期的列表:

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
4

2 回答 2

1

这是因为 Kirimati 在 1 月 1 日遭遇了 24 小时轮班。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

另外,我看了一下 Apia,似乎是:At 0000 local 30 December 2011 the clocks were moved 24 hours ahead http ://en.wikipedia.org/wiki/Apia 。

因此,由于 24 小时班次,显然这两个日期实际上并不存在于各个时区的日历中。对于所有其他人来说,这可能是正确的。

于 2013-09-19T21:08:25.673 回答
0

编辑:我最初认为 Java 不承认“太平洋/基里蒂马蒂”的含义。但事实证明确实如此。要获取 Java 将识别的所有字符串的列表,请使用:

Set<String> ids = new TreeSet<String>();
for (String id : TimeZone.getAvailableIDs())
   ids.add(id);
for (String id : ids)
  System.out.println(id);
于 2013-09-19T21:06:33.393 回答