ТЛ; др
Используйте часовой пояс, а не просто смещение.
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
предназначены для часовых поясов.