Java 8 ZoneOffset – как получить текущее системное смещение UTC

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

РЕДАКТИРОВАТЬ:
Мой вопрос отличается от этого. Я хотел бы знать текущую систему UTC, а не то, как конвертировать между представлением смещения TimeZone или хранением TimeZone.


person Allison Burgers    schedule 26.02.2017    source источник
comment
Возможный дубликат смещение часового пояса Java   -  person Muhammad Saqlain    schedule 26.02.2017


Ответы (2)


Да, возможно:

ZoneOffset.systemDefault().getRules().getOffset(Instant.now())

или вы можете заменить экземпляр Instant экземпляром LocalDateTime:

ZoneOffset.systemDefault().getRules().getOffset(LocalDateTime.now())
person Michał Szewczyk    schedule 26.02.2017
comment
Между этими двумя вариантами есть ключевое различие. Версия Instant всегда даст правильный ответ. Версия LocalDateTime даст наилучшее доступное смещение. Это связано с переходом на летнее время, где может быть два допустимых смещения для LocalDateTime или ни одного. - person JodaStephen; 16.03.2017
comment
Я могу подтвердить, что при запуске обоих примеров в Бразилии происходит следующее: при запуске вне летнего времени возвращается -03:00; если запущено в летнее время, возвращается -02:00. Проверено сменой системной даты. - person GuiRitter; 13.05.2019

Ваш запрос состоит из двух частей:

  • смещение "моя система" - таким образом, вам нужен системный часовой пояс - ZoneId.systemDefault()
  • "текущее" смещение - поэтому вам нужен текущий момент - Instant.now()

Они связаны вместе с помощью ZoneRules, чтобы получить следующее:

ZoneOffset o = ZoneId.systemDefault().getRules().getOffset(Instant.now());

Для простоты вы можете использовать OffsetDateTime:

ZoneOffset o = OffsetDateTime.now().getOffset();

Это работает, потому что OffsetDateTime.now() внутри использует как ZoneId.systemDefault(), так и Instant.now().

person JodaStephen    schedule 26.02.2017
comment
Подтверждено так же, как мой другой комментарий. - person GuiRitter; 13.05.2019
comment
Хороший компактный ответ. Кроме того, вот как перейти от ZoneOffset к миллисекундам: OffsetDateTime.now().getOffset().get(ChronoField.OFFSET_SECONDS) * 1000L; - person Wheezil; 30.06.2020