неверный часовой пояс Java - PullRequest
10 голосов
/ 21 января 2010

У меня есть экземпляр Java, который, кажется, использует совершенно неправильный часовой пояс.Вместо использования часового пояса Австралии / Сиднея, который использует Windows, он использует часовой пояс Америки / Каракаса.

Сначала я проверил время Windows через системные часы, затем проверил HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/ и ControlSet001ControlSet002.Все настроены на часовой пояс Сиднея.

Кто-нибудь знает, является ли это ошибкой в ​​Java, или это относится к времени, установленному в другом месте?

Версия Java 1.6.0_06

Ответы [ 8 ]

12 голосов
/ 21 января 2010

Убедитесь, что вы установили часовой пояс для JVM при запуске приложения:

-Duser.timezone="Australia/Sydney"
6 голосов
/ 30 июня 2010

Проверьте информацию по следующей ссылке: http://techtavern.wordpress.com/2010/04/15/java-and-incorrect-timezone-on-windows-xp/
Это показывает, что в JVM есть ошибка, приводящая к неправильному чтению часового пояса по умолчанию из реестра Windows. Пока нет исправления ошибки.

5 голосов
/ 21 января 2010

Вам следует обновить JRE / SDK , но TZUpdater может быть достаточно.

2 голосов
/ 04 марта 2011

У меня недавно была та же самая проблема, по-видимому, это вызвано неоднозначностью того, как Windows представляет свои настройки часового пояса в реестре, и Java не может правильно ее интерпретировать.

Более подробную информацию можно найти в этой статье , в которой также описаны "лекарства" для пораженной машины:

  • Изменение даты / времени вручную, а затем возврат к первоначальному правильному времени.
  • Изменение часового пояса и возврат к исходному.
  • Запрос автоматического обновления времени с сервера времени.
2 голосов
/ 21 января 2010

Попробуйте в своем приложении получить часовой пояс по умолчанию или установить часовой пояс вручную (строка комментария).

Маленький мой пример:

import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

public class Main {
    public static void main(String[] args) {
        Locale locale = Locale.getDefault();
        TimeZone localTimeZone = TimeZone.getDefault(); 
        //TimeZone localTimeZone = TimeZone.getTimeZone("Australia/Sydney");
        DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL, locale);
        dateFormat.setTimeZone(localTimeZone);
        Date rightNow = new Date();
        System.out.println(locale.toString() + ": " + dateFormat.format(rightNow));
    }
}
1 голос
/ 05 февраля 2015

Есть история таких проблем, которые приходят и уходят, и нет разумного решения. Подробнее здесь: Ошибка неправильного часового пояса Java в Windows

Редактировать: Отвечая на вопросы Тома и Фрэнсиса: Короче говоря, во время выполнения Java трудно найти правильный часовой пояс на компьютере.

Информация о реестре Windows о часовых поясах была ненадежной, и то же самое для родного API Windows, который опирается на msvcrt.dll и различные msvcrxx.dll. Существует также управляемый (.NET) API, который требует установки определенной версии .NET Framework, которая противоречит переносимости Java.

Таким образом, разработчики среды выполнения Java испытывают трудности с текущим часовым поясом в Windows, и это может продолжаться до тех пор, пока у Microsoft не появится повод для сотрудничества.

Если вы хотите, чтобы ваше приложение Java работало правильно в любом часовом поясе, предоставьте пользователям возможность исправлять часовой пояс с помощью графического интерфейса пользователя.

0 голосов
/ 27 декабря 2018

ТЛ; др

Java-программист никогда не должен полагаться на текущий часовой пояс JVM по умолчанию.

  • Всегда указывайте правильное имя часового пояса в формате Continent/Region, например Africa/Casablanca.
  • Всегда подтверждайте желаемую / ожидаемую зону с пользователем, когда это важно.

Правильные названия часовых поясов

Укажите собственное имя часового пояса в формате continent/region, например America/Montreal, Africa/Casablanca или Pacific/Auckland. Никогда не используйте 2-4 буквенные сокращения, такие как CST, EST или IST, поскольку они не истинных часовых поясов, не стандартизированы и даже не уникальны (!). Например, если вы используете IST для стандартного времени Ирландии, вы можете вместо этого получить стандартное время Индии с удивительными результатами.

ZoneId z = ZoneId.of( "America/Montreal" ) ; // Or "Pacific/Auckland", "Africa/Tunis", etc. 

Укажите часовой пояс

Никогда не полагайтесь на текущий часовой пояс JVM по умолчанию. Это значение по умолчанию может измениться.

  • Как объясняют другие Ответы, большинство JVM по умолчанию используют часовой пояс по умолчанию, используемый хост-операционной системой при запуске JVM.
  • Или скрипт, запускающий JVM, может пройти флаг, чтобы указать часовой пояс по умолчанию при запуске.
  • и во время выполнения (!) текущий часовой пояс JVM по умолчанию может быть установлен любым кодом в любом потоке любого приложения в JVM, вызывающем TimeZone.setDefault. (Кстати, TimeZone устарел на ZoneId & ZoneOffset, за исключением того метода установки, который никогда не должен вызываться, кроме как в самой экстремальной ситуации.)
  • И, конечно, пользователь или системный администратор может изменить свой текущий часовой пояс по умолчанию на хост-ОС, который, насколько я знаю, не обнаруживается при запуске JVM в большинстве реализаций.

Таким образом, по всем этим причинам текущий часовой пояс JVM по умолчанию полностью находится в руках программиста и, что еще хуже, может динамически меняться во время выполнения. Поэтому использование текущего значения по умолчанию ненадежно.

Используйте текущий часовой пояс JVM по умолчанию только для самых случайных целей. Для всего, что имеет значение, вы просто должны подтвердить предполагаемую зону с пользователем . Это неудобная истина, которой часто сопротивляются программисты, но, тем не менее, это правда.


Locale

Подсказка: то же самое для Locale. Текущий язык по умолчанию JVM может совпадать или не совпадать с языком операционной системы хоста, может измениться в любой момент и поэтому ненадежен. Всегда подтверждайте желаемое / ожидаемое Locale с пользователем.


О java.time

Фреймворк java.time встроен в Java 8 и более поздние версии. Эти классы заменяют проблемные старые устаревшие классы даты и времени, такие как java.util.Date, Calendar, SimpleDateFormat и java.util.TimeZone.

Проект Joda-Time , теперь в режиме обслуживания , рекомендует перейти на классы java.time .

Чтобы узнать больше, см. Oracle Tutorial . И поиск переполнения стека для многих примеров и объяснений. Спецификация JSR 310 .

Вы можете обмениваться java.time объектами напрямую с вашей базой данных. Используйте драйвер JDBC , совместимый с JDBC 4.2 или более поздней версии. Нет необходимости в строках, нет необходимости в java.sql.* классах.

Где получить классы java.time?

Проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является полигоном для возможных будущих дополнений к java.time. Здесь вы можете найти некоторые полезные классы, такие как Interval, YearWeek, YearQuarter и more .

0 голосов
/ 05 января 2012

У меня была та же ошибка, когда я устанавливал свой часовой пояс на стандартное время Малайского полуострова, JVM дала мне часовой пояс Венесуэлы.

У меня работает следующее исправление:

В редакторе реестра отредактируйте свой часовой пояс на другой часовой пояс (я пытался поместить другой текст, например «Сингапурское время». Вы можете найти реестр здесь:

HKEY_LOCAL_MACHINE / SYSTEM / CurrentControlSet / Control / TimeZoneInformation

И затем я сбрасываю его обратно в желаемый часовой пояс с помощью панели управления, настройки даты и времени. Когда я возвращаюсь в редактор реестра, я вижу, что он возвращается к стандартному времени Малайского полуострова. И моя JVM теперь правильно читает ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...