Почему java 8 time не показывает правильное время для часового пояса Etc / GMT + 1 - PullRequest
2 голосов
/ 02 июля 2019
ZonedDateTime now = ZonedDateTime.now(ZoneId.of("Etc/GMT+1"));

значение этого параметра при отладке показывает 2019-07-02T14: 23: 57.463-01: 00 [Etc / GMT + 1]

это должно быть 16:23, чего мне не хватает.часы почему-то на 2 часа медленнее?

1 Ответ

3 голосов
/ 02 июля 2019

ТЛ; др

Используйте часовой пояс, а не просто смещение.

ZonedDateTime.now( 
    ZoneId.of( "Europe/Dublin" )
)

Подробнее

В современных протоколах число часов-минут-секунд в смещении рассматривается как положительные числа, равные впереди базовой линии (GMT / UTC), а отрицательные числа как позади базовый уровень. Некоторые старые протоколы являются обратными. Ваш Etc/GMT+1, кажется, имеет противоположный стиль.

Лучшее решение - использовать часовые пояса, а не просто смещение. Смещение - это просто количество часов, минут и секунд. Часовой пояс намного больше. Часовой пояс - это история прошлых, настоящих и будущих изменений смещения, используемых людьми определенного региона.

Часовой пояс имеет имя в формате Continent/Region. Например, America/Montreal, Europe/Paris и Pacific/Auckland.

ZoneId z = ZoneId.of( "Europe/Dublin" ) ;
ZonedDateTime zdt = ZonedDateTime.now( z ) ;

Создайте строку в стандартном формате ISO 8601, расширенном для добавления названия зоны в квадратных скобках.

String output = zdt.toString() ;

Большая часть вашей бизнес-логики, ведения журналов и изменения данных должна быть в UTC. Чтобы настроить UTC, извлеките Instant из вашего ZonedDateTime. Тот же момент, та же точка на временной шкале, но другое время на настенных часах.

Instant instant = zdt.toInstant() ;

Генерация строки в стандартном формате ISO 8601.

String output = instant.toString() ;

Ваш пример

Так что теперь мы можем вернуться к рассмотрению вашей конкретной ситуации.

Давайте разберем данную строку с [Etc/GMT+1] в качестве имени зоны.

String input = "2019-07-02T14:23:57.463-01:00[Etc/GMT+1]" ;
ZonedDateTime zdtInput = ZonedDateTime.parse ( input );

Затем настройте на UTC.

Instant instant = zdtInput.toInstant ();

Настройте снова на Europe/Dublin.

ZoneId zDublin = ZoneId.of( "Europe/Dublin");
ZonedDateTime zdtDublin = zdtInput.withZoneSameInstant ( zDublin );

Дамп на консоль.

System.out.println ("zdtInput: " + zdtInput );
System.out.println ("instant: " + instant );
System.out.println ("zdtDublin: " + zdtDublin );

См. Этот код, запущенный в режиме реального времени на IdeOne.com .

zdtInput: 2019-07-02T14: 23: 57.463-01: 00 [Etc / GMT + 1]

мгновенный: 2019-07-02T15: 23: 57,463Z

Зд.Дублин: 2019-07-02T16: 23: 57.463 + 01: 00 [Европа / Дублин]

час 14

Конечно, мы видим, что день с [Etc/GMT+1] равен часу отстает UTC (старое обратное значение смещения часов) с часом 14.

час 15

UTC (смещение нуля часов-минут-секунд) имеет час 15.

час 16

В часовом поясе Дублина используется стандартное ирландское время (IST), UTC +1, а не Летнее время (DST) на данный момент. Таким образом, мы видим его час в 16, час впереди из UTC 15 час.

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


Кстати, когда вы хотите работать со смещениями, а не с часовыми поясами, используйте классы OffsetDateTime & ZoneOffset. Классы ZonedDateTime & ZoneId предназначены для часовых поясов.

...