Правильная поддержка часового пояса в J2ME - PullRequest
2 голосов
/ 03 февраля 2011

Мне нужна точная поддержка часовых поясов в моем приложении BlackBerry.Поскольку он запускает J2ME, Joda Time не вариант.С помощью некоторых других пользователей SO я выяснил, как сделать так, чтобы поддержка встроенного в 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 году произойдет 13 марта в 2 часа ночи, но в Java это произойдет в полночь 14 марта.Это означает, что это неправильно почти весь день.Это неприемлемо.

Я приступил к реализации собственного анализатора tzdata на основе this и доставке файлов tzdata с моим приложением, но мне интересно, есть ли лучший способ.Вы знаете один?Я не могу быть первым, кто решит эту проблему, не так ли?

1 Ответ

3 голосов
/ 03 февраля 2011

Я понял это. Я не виноват, я.

Проблема в том, что я использовал 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));
...