我的BlackBerry应用程序需要准确的时区支持。因为它运行J2ME,所以Joda Time不是一个选项。在其他一些人的帮助下,我已经找到了如何让Java的内置时区支持为我工作,但事实证明它仍然可以从日光节省转换到非日光节省错误。您可以自己尝试,即使是在Java 6上:
TimeZone zone = TimeZone.getTimeZone("America/Los_Angeles");
Calendar calendar = Calendar.getInstance();
calendar.setTimeZone(zone);
calendar.set(2011, Calendar.MARCH, 13, 1, 0, 0);
System.out.println(zone.getOffset(1, calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH), calendar.get(Calendar.DAY_OF_WEEK), calendar.get(Calendar.MILLISECOND)));
calendar.set(2011, Calendar.MARCH, 13, 6, 0, 0);
System.out.println(zone.getOffset(1, calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH), calendar.get(Calendar.DAY_OF_WEEK), calendar.get(Calendar.MILLISECOND)));
calendar.set(2011, Calendar.MARCH, 13, 23, 59, 59);
System.out.println(zone.getOffset(1, calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH), calendar.get(Calendar.DAY_OF_WEEK), calendar.get(Calendar.MILLISECOND)));
calendar.set(2011, Calendar.MARCH, 14, 0, 0, 1);
System.out.println(zone.getOffset(1, calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH), calendar.get(Calendar.DAY_OF_WEEK), calendar.get(Calendar.MILLISECOND)));
2011年的转换时间是3月13日凌晨2点,但是Java在3月14日的午夜时分进行了切换。这意味着它几乎整整一天都是错的。这是不可接受的。
我已经开始实现我自己的基于this的tzdata解析器,并使用我的应用程序发送tzdata文件,但我想知道是否有更好的方法。你知道吗?我不能成为第一个遇到这个问题的人,可以吗?
答案 0 :(得分:3)
我明白了。我不应该责怪Java。
问题是我使用calendar.get(Calendar.MILLISECOND)作为TimeZone.getOffset()的最后一个参数。该值是日历中日期的毫秒部分,但TimeZone.getOffset()所期望的是整天过程中经过的毫秒数。
这是更正后的代码:
calendar.set(2011, Calendar.MARCH, 13, 1, 0, 0);
int millis =
calendar.get(Calendar.MILLISECOND) +
calendar.get(Calendar.SECOND) * 1000 +
calendar.get(Calendar.MINUTE) * 60 * 1000 +
calendar.get(Calendar.HOUR_OF_DAY) * 60 * 60 * 1000;
System.out.println(zone.getOffset(1, calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH), calendar.get(Calendar.DAY_OF_WEEK), millis));