Часовой пояс Java 8 для Instant.EPOCH неверен - PullRequest
5 голосов
/ 29 сентября 2019

У меня машина linux, и ее часовой пояс установлен как Азия / Катар. Когда я печатаю Instant.EPOCH с помощью средства форматирования, это дает мне неверную информацию о зоне, в то время как для Instant.now () информация о зоне верна. Ниже мой код и его вывод. Может кто-нибудь, пожалуйста, помогите мне, почему это несоответствие?

import java.util.Date;
import java.time.format.DateTimeFormatter;
import java.time.Instant;
import java.time.ZoneId;

public class DateTest {
   public static void main(String[] args) {
      String pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS Z";
      Instant myInstant = Instant.EPOCH;
      Instant myInstantNow = Instant.now();
      DateTimeFormatter formatter =  DateTimeFormatter.ofPattern(pattern).withZone(ZoneId.systemDefault());
      System.out.println(formatter.format(myInstant));
      System.out.println(formatter.format(myInstantNow));
   }
}

Вывод кода:

1970-01-01T04:00:00.000 +0400
2019-09-29T18:30:14.766 +0300

Версия Java: "1.8.0_181"

Тот же код, если я запускаю в Windows, он работает нормально. Я также получаю +0300 за Instant.EPOCH.

Ответы [ 2 ]

7 голосов
/ 29 сентября 2019

TL; DR: Ваши результаты по Linux верны и, как и ожидалось.

В 1970 году Катар был по смещению +04: 00 по Гринвичу. Эпоха наступила 1 января 1970 года. В 1972 году Катар перешел со смещения +04: 00 на +03: 00. Источник: Вкл. Часовой пояс в Дохе, Катар (Ad Dawhah) , в Изменения часового пояса для: выберите 1970–1979.

Что пошло не так на вашемКомпьютер Windows, тогда? С моей стороны это предположение: как я читаю часовые пояса по умолчанию в документации Windows, Windows не предлагает часовой пояс Азии / Катара в качестве параметра в Windows. Поэтому я предполагаю, что для вашей Windows установлено Стандартное арабское время в соответствии с таблицей, с которой я только что связался, что, в свою очередь, означает UTC + 03: 00. Стандартное арабское время (или Стандартное время Аравии; сокращенно AST) используется, например, в Кувейте, Ираке и Йемене. Но эти страны были на смещении +03: 00 все время с 1970 года и раньше. Поэтому, когда Java пытается выбрать часовой пояс по умолчанию из Windows, она может легко получить часовой пояс с этой историей, а не с правильной историей для Катара. Как я уже сказал, пока это предположение. Но вы можете легко проверить. На компьютере с Windows попробуйте:

    System.out.println(ZoneId.systemDefault());

Если он напечатает Asia/Qatar, мое предположение было неверным. Если он печатает что-то вроде GMT+03:00, я был прав. Если он печатает что-то еще, я могу или не могу.

Редактировать: Несколько дальнейших ссылок: AST - Стандартное время Аравии (Стандартное время) приводит Кувейт в качестве примера города. Изменения во времени в Кувейте за последние годы сообщает нам, что Кувейт также находится в смещении +03: 00 с 1950 года.

Дальнейшее редактирование: Спасибо за подтверждение того, что Java на вашем компьютере Windows печатает Азию/ Эр-Рияд в качестве часового пояса по умолчанию. Эр-Рияд, Саудовская Аравия, находится на смещении +03: 00 с 1947 года. Это, по крайней мере, частично объясняет, почему вы получаете это смещение, даже если оно не подходит для Катара. Источник

1 голос
/ 29 сентября 2019

При первом наблюдении я думаю, что разница в летнем времени имеет место, поскольку ваши даты показывают январь (зимнее время) и сентябрь (летнее время), однако, насколько я вижу, Катар в настоящее время не использует эту систему.

Однако, если мы посмотрим в прошлое, мы можем узнать, что Катар изменил зону UTC 1 июля 1972 года с GST (-04: 00) на AST (-03: 00), поэтому я предполагаю, что результатыверный. Эту информацию можно найти по адресу Часовой пояс и изменения часов в Дохе, Катар .

Проблема в том, что машина Windows использует текущий UTC Qatari, поскольку платформа на базе Windows отслеживает некоторые история. Подробнее на Надежен ли часовой пояс Windows в реестре? .

...