В 2019 году никого не должно волновать, почему классы SimpleDateFormat
и TimeZone
ведут себя так же, как и они, поскольку мы должны были отказаться от использования этих классов много лет назад.Василий Бурк дал вам ответ, который вы должны хотеть.Этот ответ попытается удовлетворить ваше любопытство, но, пожалуйста, не используйте его, чтобы заставить SimpleDateFormat
вести себя.Вам будет намного лучше не с использованием этого класса.
Я предполагаю, что ваш часовой пояс JVM - Европа / Лондон (мы увидим, что это имеет значение).Когда я установлю свой часовой пояс таким образом и свою локализацию в Великобритании, я смогу точно воспроизвести ваши результаты.
Проанализировал "13:40" со средним временем по Гринвичу для часового пояса 01.01.1970, 13:40
Разбор 13:40 в вашем часовом поясе по умолчанию дает 13:40 в вашем часовом поясе по умолчанию, никаких сюрпризов.Поскольку Великобритания была со смещением UTC +01: 00 зимой 1970 года, это время совпадает с 12:40 UTC (когда дата не указана, SimpleDateFormat
использует значение по умолчанию 1 января 1970 года).Когда на выходе выдается Greenwich Mean Time
, это ошибка.
Проанализировано "13:40" с часовым поясом по тихоокеанскому стандартному времени на 01.01.1970, 22: 40
В 1970 году западное побережье США отстало от UTC на 8 часов, то есть от Великобритании на 9 часов.Поэтому, когда вы говорите SimpleDateFormat
, что предполагается, что 13:40 находится в часовом поясе Америки / Лос-Анджелеса, оно разбирается во время 13:40 по тихоокеанскому времени, то есть в 21:40 UTC или в 22:40 по британскому времени (Америка / Лос-Анджелескак TimeZone
интерпретирует PST, но он устарел, не полагайтесь на него.) MessageFormat
использует часовой пояс по умолчанию для печати времени, поэтому печатается 22:40.
Parsed "13:40 UTC "с часовым поясом по Гринвичу Среднее время до 01.01.1970, 14:40
Поскольку (как уже упоминалось) Лондон находился в смещении +01: 00 в это время, а с MessageFormat
использует часовой пояс по умолчанию, 14:40 - правильный и ожидаемый результат.dateFormat.parse(dateString)
разбирается на Date
, еще один плохо спроектированный и давно устаревший класс.Date
является моментом времени и не может содержать смещение UTC (в отличие от класса OffsetTime
, который правильно использует Базилик Бурк).И ваши наблюдения верны: SimpleDateFormat
использует UTC
из строки для интерпретации 13:40 в момент времени (а не в настройке часового пояса).MessageFormat
не может знать, что время было ранее проанализировано с 13:40 UTC.
Выполнено синтаксический анализ "13:40 UTC" с часовым поясом Тихоокеанского стандартного времени на 01.01.1970, 14: 40
Поскольку SimpleDateFormat
использует UTC
из строки для интерпретации 13:40 в момент времени, мы получаем то же время, что и выше.