Извлечение вручную установленного часового пояса на компьютере с Windows

#java #java-8

#java #java-8

Вопрос:

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

Локально мой регион часового пояса — Америка / New_York с использованием ZoneId.systemDefault() (EDT). Тем не менее, я установил часовой пояс моего компьютера на тихоокеанское время (PDT). Я попробовал указанный ниже код. Каков наилучший способ добиться этого в Java 8?

 LocalDateTime currentDateTime = LocalDateTime.of(date.getYear(), date.getMonth(), date.getDay(), hour, minute, 0);
        ZonedDateTime zonedDateTime = currentDateTime.atZone(ZoneId.systemDefault());
        date = Date.from(zonedDateTime.toInstant());
  

Я ожидаю, что часовой пояс будет Amrica / Dawson или America / Tijuana (UTC -08:00), но вместо этого я получаю America / New_York (UTC -05:00)

Комментарии:

1. Меня больше интересует, как вы получаете, -05:00[America/New_York] когда в настоящее время летнее время (я получаю -04:00[America/New_York] ).

2. Calendar.getInstance().getTimezone() ?

3. Используя timedatectl в Centos 7, изменение системного часового пояса дает мне ожидаемый результат, поэтому я предполагаю, что то, как вы пытаетесь изменить часовой пояс вашей системы, не делает того, что вы думаете

4. @markspace уже пробовал это. Хотя спасибо.

5. @Мэтт привет. Каким образом вы изменили свой часовой пояс? Я изменил свой, используя настройки Windows «Дата и время» > «Изменить часовой пояс».

Ответ №1:

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

 TimeZone.setDefault(null);
System.setProperty("user.timezone", "");
//(above) force fetches and sets the JVM to the timezone the system is set to
LocalDateTime currentDateTime = LocalDateTime.of(date.getYear(), date.getMonth(), date.getDay(), hour, minute, 0);
ZonedDateTime zonedDateTime = currentDateTime.atZone(ZoneId.systemDefault());
date = Date.from(zonedDateTime.toInstant());
  

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

 TimeZone.setDefault(null);
System.setProperty("user.timezone", "");
  

(выше) Позволило мне очистить ранее установленный часовой пояс JVM.

РЕДАКТИРОВАТЬ 26.04.2019

Я обновил свою логику для поддержки экономии дневного света по тихоокеанскому времени. Я столкнулся с проблемой, когда мое время устанавливало PST вместо PDT, поэтому вместо приведенной выше логики я изменил его, чтобы захватить идентификатор зоны и использовать его с классом Calendar. Ниже приведена завершенная логика:

 TimeZone.setDefault(null);
System.clearProperty​("user.timezone"); //04/26/2019 EDIT This was suggested as a cleaner way of clearing the user timezone in the system.
//(above) force fetches and sets the JVM to the timezone the system is set to
System.out.println("Zone: " ZoneId.systemDefault() " isDaylightsavings? " ZoneId.systemDefault().getRules().isDaylightSavings(Instant.now()) " currentDateTime: " currentDateTime);
String timeZone = "" ZoneId.systemDefault();
Calendar selectedDate = Calendar.getInstance(TimeZone.getTimeZone(timeZone)); // important when it comes to determining PDT or PST
date = selectedDate.getTime();
  

Комментарии:

1. Я думаю, System.clearProperty​("user.timezone"); было бы чище, чем System.setProperty("user.timezone", "");

2. @Holger Не могли бы вы объяснить преимущества?

3. Это документирует намерение: вы хотите очистить свойство (удалить явный параметр), а не устанавливать его в пустую строку. Отсутствие сопоставления также может сэкономить немного памяти по сравнению с сохранением сопоставления с пустой строкой, но это незначительно.

4. @Holger Спасибо! Хорошая вещь, которую следует отметить всем, кто читает это.