public static OffsetDateTime convertFrom(Date source) { if (source instanceof Timestamp) { return ((Timestamp) source).toLocalDateTime() .atOffset(ZoneOffset.UTC); } return source.toInstant().atOffset(ZoneOffset.UTC); }
Объект, переданный вашему методу, был
java.sql.Timestamp
, а неDate
. Мы можем видеть этот факт по тому, как он был напечатан:2018-07-11 15:45:13.0
- это возвращаемое значение изTimestamp.toString()
. КлассTimestamp
реализуется как подклассDate
, но это не означает, что мы не можем и не должны обрабатывать его какDate
. Документация предупреждает нас:Из-за различий между классом
Timestamp
и классомjava.util.Date
, упомянутым выше, рекомендуется, чтобы код не отображал значенияTimestamp
в качестве экземпляраjava.util.Date
. Взаимодействие наследования междуTimestamp
иjava.util.Date
действительно означает наследование реализации, а не наследование типа.В реализации выше я предположил, что вы не можете смягчить возможность получения
Timestamp
аргумент, поэтому я обрабатываю возможность, насколько я могу. Однако код все еще хрупкий, потому что иногдаTimestamp
обозначает точку во времени (я должен сказать, что это точка), в других случаях она обозначает дату и час дня. Предоставлено, чтоTimestamp
не содержит в нем часового пояса, два не совпадают. Я понимаю, что ваш образецTimestamp
обозначает дату и время 2018-07-11 15: 45: 13.0, и вы хотите, чтобы это было интерпретировано в UTC. Мой код делает это (ваш код в вопросе, с другой стороны, правильно обрабатывает ситуацию, когдаTimestamp
обозначает момент времени). Кроме того, даже если в моем коде не указано никакого часового пояса, его поведение по-прежнему зависит от настройки часового пояса вашего JVM.Когда я передаю
Timestamp
из2018-07-11 15:45:13.0
в мой метод выше, он возвращаетOffsetDateTime
из2018-07-11T15:45:13Z
.Двойной характер
Timestamp
является неудачным и запутанным, и единственным реальным решением было бы, если бы вы могли полностью отказаться от этого класса. КлассDate
тоже плохо разработан, и оба устарели и заменены java.time, современным Java-API датой и временем. Если вы не можете избежать старых классов в своем коде, я, безусловно, понимаю ваше желание преобразовать в современнуюOffsetDateTime
первую вещь. Если, с другой стороны, я правильно понимаю, что дата и время проходят через JSON, вы можете проанализировать его на своей стороне без каких-либо старых классов даты и времени, что было бы хорошим решением вашей проблемы. И при любых обстоятельствах, если ваша реальная цель состоит в том, чтобы представить момент времени в нейтральном часовом поясе, я согласен с Базилем Бурком в предпочтенииInstant
поOffsetDateTime
в UTC.Ссылка : Документация
java.sql.Timestamp