SimpleDateFormat метод анализа тайны - PullRequest
0 голосов
/ 16 октября 2018

Мне известно, что SimpleDateFormat.parse полагается на API Календаря, который зависит от местного часового пояса JVM (компьютера).Предположим, что часовой пояс JVM равен IST.

SimpleDateFormat srcDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
srcDateFormat.setTimeZone(TimeZone.getTimeZone("EST"));
Date objDt = srcDateFormat.parse("2018-10-16 11:28:25"); //Time : 21:58:25 

Из выходных данных кажется, что он преобразуется из EST в IST (локальный часовой пояс JVM).

SimpleDateFormat srcDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
srcDateFormat.setTimeZone(TimeZone.getTimeZone("IST"));
Date objDt = srcDateFormat.parse("2018-10-16 11:28:25"); //Time : 11:28:25 

В этом случае время остается неизменным.В этом случае я установил часовой пояс так же, как местный часовой пояс JVM.

Пожалуйста, помогите мне понять поведение метода parse.Тем не менее мне любопытно узнать причину такого поведения.Я знаю, что унаследованные классы java.util.Date и java.text.SimpleDateFormat устарели.

Ссылки:

1 Ответ

0 голосов
/ 17 октября 2018

Во-первых, вы правы, что Date и SimpleDateFormat являются устаревшими классами и теперь устарели.Поэтому я рекомендую вам не использовать их и использовать вместо этого java.time, современный Java-интерфейс даты и времени.Среди многих преимуществ гораздо более явные сведения о преобразованиях между часовыми поясами, которые, как я ожидаю, помогут вам понять, что делает код.

Во-вторых, вы делаете ряд вещей неправильно или, по крайней мере, неадекватно:

  1. Не храните дату и время в виде строк.Всегда храните их как объекты даты и времени в Java.Когда вы сделаете это, вам никогда не потребуется преобразовывать строку даты и времени из одной зоны в другую.Instant (класс из java.time) - это момент времени, и, насколько я вижу, тот, который вы должны использовать здесь.
  2. Не полагайтесь на трехбуквенные сокращения часовых поясов.Очень многие из них неоднозначны, включая как IST, так и EST, и последний не является истинным часовым поясом, поэтому то, что вы получаете в это время года (когда зона Америка / Нью-Йорк использует EDT, а не EST), я нене знаю.
  3. И повторяюсь, используйте современные классы, а не устаревшие.

Из любопытства, что случилось?

Старомодный Date представляет момент времени независимо от часового пояса (внутренне он сохраняет свое значение в виде количества миллисекунд с начала эпохи, но это деталь реализации, о которой нам не нужно знать или беспокоиться).

В вашемВ первом примере ваша строка разбирается на момент времени, соответствующий 16:28:25 UTC, 21:58:25 в Индии, 12:28:25 в Нью-Йорке или 11:28:25 на Ямайке.Я упоминаю Ямайку, потому что это одно из немногих мест, где восточное стандартное время (EST) используется круглый год.Большинство мест, которые используют EST, делают это только зимой, а не в это время года.Когда вы смотрите на Date в вашем отладчике, отладчик вызывает toString на Date, чтобы получить строку для отображения.toString в свою очередь использует часовой пояс JVM для генерации строки.В вашем случае это Азия / Калькутта, поэтому вы получаете 21: 58: 25.

Во втором случае эта же строка анализируется в момент времени, который соответствует 05:58:25 UTC, 11: 28: 25 в Индии, 01:58:25 в Нью-Йорке или 00:58:25 на Ямайке.Ваш отладчик снова вызывает toString, который снова использует часовой пояс вашей JVM и преобразуется обратно в 11:28:25 IST.Когда вы анализируете и печатаете в одном часовом поясе, вы получаете одно и то же время дня назад.

Ссылки

...