2010-12-07 2 views
3

В моем клиенте, у меня есть этот код:Joda часовой пояс отличается от JDK-х

System.out.println("Java tz: " + TimeZone.getDefault()); 
System.out.println("Joda tz: " + ISOChronology.getInstance()); 

Эти две строки запустить один за другим. Я никогда не устанавливал часовой пояс или user.timezone вручную, просто полагаюсь на значения по умолчанию, прочитанные из локальной системы OS &.

При выполнении, они производят: часовой пояс

Java tz: sun.util.calendar.ZoneInfo[id="UTC",offset=0,dstSavings=0,useDaylight=false,transitions=0,lastRule=null] 
Joda tz: ISOChronology[America/Phoenix] 

система действительно Phoenix, а не UTC. Как Джода может быть прав, а JDK ошибается?

EDIT: Это хост для Windows 7 x64, JRE - 1.6.22 x64.

EDIT 2: Не пытайтесь воспроизвести его. Это происходит только в некоторых, а не во всех системах (например, несколько десятков в базе данных 3k). Я уже знаю проверки Джоды user.timezone, а затем TimeZone.getDefault(). Поэтому я ищу объяснение, как это может быть разным, когда я вызываю TimeZone и Joda делает это сам.

+0

Я тестировал его на своей машине с Windows с JDK 1.6.0_22, и он показывает мой часовой пояс, а не UTC. Может быть, вы должны добавить дополнительную информацию: OS, JDK-версия, возможно, некоторые переменные среды? – 2010-12-07 08:47:11

+0

@ Michał: Спасибо, обновлено. – 2010-12-07 08:49:10

ответ

7

Когда вы говорите «значения по умолчанию, прочитанные из локальной системы ОС &», не существует ни одного, четко определенного места для чтения этого значения по умолчанию. Даже сама документация по API говорит

Получает по умолчанию TimeZone для этого хоста. Источник по умолчанию TimeZone может отличаться в зависимости от реализации.

Таким образом, простой ответ заключается в том, что Joda и ваша JVM выписывают часовой пояс по умолчанию из разных источников информации. Следует помнить, что по умолчанию является предположением, а не тем, к чему JVM может получить окончательный доступ.

Для 1.5.0_06 JVM Sun, на Linux, используется следующий порядок:

  1. Надеется переменной окружения TZ
  2. ищет файл/и т.д./sysconfig/часы и пытается найти «ZONE "запись.
  3. Сравнивает содержимое fo/etc/localtime с содержимым каждого файла в/usr/share/zoneinfo рекурсивно. Когда содержимое совпадает, оно возвращает путь и имя файла, на которые ссылается/usr/share/zoneinfo.

Joda 1.6.2 использует:

  1. Система собственности user.timezone.
  2. Если приведенное выше значение null или недействительный идентификатор, используется значение JDK TimeZone.
  3. Если это не удается, используется UTC.

Так если у вас есть вышеуказанные версии JDK и Joda, я полагаю, что свойство user.timezone может быть установлен в вашей среде.Однако другие версии могут использовать другие алгоритмы для получения значения по умолчанию.

Edit: В JDK Солнца 1.6.0_22, поиск по умолчанию первого инспектирует user.timezone собственности, а также, если он не найден, он ищет user.country свойства для того, чтобы получить значение по умолчанию для страны. Если ни один из них не установлен, используется значение по умолчанию GMT. Таким образом, результаты, которые вы наблюдаете, могут измениться с вашей версией JVM.


Edit 2: Если у вас есть источник как (и в самом деле источники являются доступными), то вы можете просто отслеживать его! Пройдите через вызов Joda, чтобы убедиться, что он действительно отложил до java.util.TimeZone.getDefault() и посмотрел, что это за возвращаемое значение. Затем вызовите метод JDK напрямую и посмотрите, что вы получаете.

Рассматривая источники JDK, кажется, что часовой пояс по умолчанию доступен через наследуемый поток локально. Таким образом, если кто-то где-то звонит TimeZone.setDefault(), он может быть или не быть видимым в других потоках, в зависимости от того, искали ли они уже версию. Если вы получаете, по-видимому, аномальные результаты отладки вызовов, это может быть просто из-за того, что разные потоки могут иметь разные часовые пояса по умолчанию.

Смежные вопросы