Дата разбора через несколько минут - PullRequest
0 голосов
/ 25 июня 2018

В последнее время я имел дело с отвратительным гейшенком.Это напомнило мне о известной 500-мильной истории по электронной почте .Я анализирую полученную дату в значении ISO 8601, но анализируемый объект Date иногда занимает много минут в будущем.Однако, когда я пытаюсь проанализировать те же данные в модульном тесте, получающаяся дата всегда верна.

Вот формат, который я получаю:

2018-06-25T13:50:53.984771

Я анализирую его с JSON используя Jackson:

new StdDateFormat().parse(timestamp);

Вот несколько примеров разобранных дат:

2018-06-25T13:50:59.337828
Mon Jun 25 15:56:36 CEST 2018

2018-06-25T13:50:53.984771
Mon Jun 25 16:07:17 CEST 2018

Разница в два часа хорошая, это только часовой пояс, но как насчет минут?Похоже, они случайно смещены!

Ответы [ 3 ]

0 голосов
/ 26 июня 2018

java.time

Вы используете ужасно хлопотные старые классы даты и времени (Date, Calendar) из самых ранних версий Java.Эти классы теперь унаследованы, их несколько лет назад вытеснили java.time классы.

Я не пользователь Джексона, поэтому я не знаю, добавила ли Джексон встроенную поддержку для java.time пока.Но я думаю, что это вероятно.

Если нет, похоже, вы можете добавить модуль поддержки Джексона для этой цели.См. эту статью , этот вопрос , и этот сайт GitHub .

java.time классы используют наносекундное разрешение,Это означает до девяти (9) десятичных цифр доли секунды.Этого более чем достаточно для 6 цифр в ваших входах.

Зональный или незонированный

У вас есть другая проблема, другой природы.Вы берете данные для даты и времени, в которых отсутствует какая-либо концепция часового пояса или смещения от UTC.Затем вы сохраняете его в другой тип , тип с часовым поясом.Нехорошо.Вы ввели значение, где никто не был заслужен.Это все равно, что взять общее число, предполагаемое в качестве цены, и затем произвольно применить определенную валюту, не указанную во входных данных.

Вы должны анализировать входные данные, такие как 2018-06-25T13:50:53.984771 как LocalDateTime.У этого типа намеренно отсутствует какой-либо часовой пояс или смещение от UTC, например, ваш ввод.Этот тип не представляет определенный момент, является не точкой на временной шкале, поскольку он не имеет реального значения, пока вы не примените контекст зоны / смещения.

Для получения дополнительной информации выполните поиск переполнения стека для LocalDateTime, ZonedDateTime, OffsetDateTime и Instant.В частности, для некоторых моих ответов, ищите "Санта".


О java.time

java.time *Платформа 1052 * встроена в Java 8 и более поздние версии.Эти классы заменяют проблемные старые устаревшие классы даты и времени, такие как java.util.Date, Calendar и & SimpleDateFormat.

Проект Joda-Time , теперь в режиме обслуживания , рекомендует перейти на классы java.time .

Чтобы узнать больше, см. Oracle Tutorial .И поиск переполнения стека для многих примеров и объяснений.Спецификация: JSR 310 .

Вы можете обмениваться java.time объектами напрямую с вашей базой данных.Используйте драйвер JDBC , совместимый с JDBC 4.2 или более поздней версии.Нет необходимости в строках, нет необходимости в java.sql.* классах.

Где получить классы java.time?

  • Java SE 8 , Java SE 9 , Java SE 10, а позже
    • Встроенный.
    • Часть стандартного Java API с встроенной реализацией.
    • Java 9 добавляет некоторые незначительные функции и исправления.
  • Java SE 6 и Java SE 7
    • Большая часть функций java.time перенесена на Java 6 & 7 в ThreeTen-Backport .
  • Android
    • Более поздние версии реализации связки Android классов java.time.
    • Для более ранних версий Android (<26) адаптируется проект <a href="https://github.com/JakeWharton/ThreeTenABP" rel="nofollow noreferrer"> ThreeTenABP ThreeTen-Backport (упомянуто выше).См. Как использовать ThreeTenABP… .

ThreeTen-Extra Проект расширяет java.time дополнительными классами.Этот проект является полигоном для возможных будущих дополнений к java.time.Здесь вы можете найти несколько полезных классов, таких как Interval, YearWeek, YearQuarter и more .

0 голосов
/ 26 июня 2018

Используйте jackson-modules-java8 и типы java.time, рекомендованные Бэзилом Бурке в его ответе .У меня нет опыта работы с jackson-modules-java8, но он определенно должен правильно анализировать доли секунд с точностью до 9 знаков после запятой, и он поддерживает современные типы даты и времени.

0 голосов
/ 25 июня 2018

Я отвечаю на свой вопрос, надеясь, что это однажды спасет чью-то шкуру.

Проблема не проявилась в модульных тестах, поэтому я подумал, что, возможно, что-то не так с сервером.Я перепробовал все, что, по моему мнению, могло быть не так, включая исследование странных часовых поясов, которые смещены на 15 минут, выяснение того, откуда Java на самом деле отнимает время, и так далее.В конце концов, у меня не было другого выбора, кроме как развернуть несколько модификаций кода, чтобы разделить, где может быть проблема.Это оказался синтаксический анализатор.

Вот ошибка, которая вызвала проблему: https://github.com/FasterXML/jackson-databind/issues/1668

Я смог найти ее, только когда друг заметил, что количество миллисекунд наКонец отметки времени соответствует смещению в минутах:

Original: 2018-06-25T13:50:53.984771
Milliseconds: 984771 ms = 16 minutes 24.77 seconds
Result: Mon Jun 25 16:07:17 CEST 2018

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

Причина, по которой проблема не проявилась в модульных тестах, заключается в том, что созданная мной библиотека использует более новую версию Jackson, которая больше не используется.содержит ошибкуОднако приложение, использующее библиотеку, уже содержало Джексона, и, поскольку Maven выбирает определение библиотеки , наиболее близкое к проекту , создаваемому при разрешении зависимостей, оно заменило мою более новую версию Джексона в библиотеке с помощьюстарший объявлен в своем собственном pom.xml.Так что, в конце концов, это был случай самозваной зависимости.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...