Поскольку класс SimpleDateFormat
общеизвестно проблематичен и давно устарел, а также не поточнобезопасен, я подумал, что покажу вам, как решить вашу задачу с помощью java .time, современного Java API даты и времени , На данный момент я предполагаю, что вы не можете изменить тип вашего поля date
, оно должно быть Date
, а также что вы не можете изменить формат / с. Я переписал класс из вашего собственного ответа следующим образом:
public class DateDeserializer extends StdDeserializer<Date> {
private static final DateTimeFormatter formatter
= DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm[:ss] z", Locale.ENGLISH);
public DateDeserializer() {
this(null);
}
public DateDeserializer(Class<?> vc) {
super(vc);
}
@Override
public Date deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
String dateString = p.getText();
if (dateString.isEmpty()) {
//handle empty strings however you want,
//but I am setting the Date objects null
return null;
}
Instant parsedInstant = formatter.parse(dateString, Instant::from);
return Date.from(parsedInstant);
}
}
В строке шаблона формата я использую квадратные скобки, []
, около дополнительных секунд минуты. DateTimeFormatter
является поточно-ориентированным (напротив SimpleDateFormat
), поэтому безопасно иметь только один экземпляр stati c, даже если он используется из нескольких потоков. DateTimeFormatter.parse()
выдает исключение времени выполнения (непроверенное исключение), если он не может проанализировать строку, поэтому я не нашел причин, чтобы сделать это явным в нашем собственном коде.
Если вы могли бы внести любое из следующих изменений , это могло бы улучшить положение вещей:
- Обучите источник ваших строк даты и времени использовать формат ISO 8601, например
2020-02-13T16:02:11-05:00
. Используемый ими в настоящее время формат представляет собой своеобразное сочетание ISO 8601 и не-ISO, поэтому вы и они на самом деле не получаете ни преимущества стандарта, ни полных потенциальных преимуществ более удобочитаемого формата. Форматеры для ISO 8601 встроены в java .time, поэтому использование стандарта избавит нас от необходимости самостоятельно определять любой форматтер. И секунды являются необязательными в ISO 8601, поэтому они могут отправлять строки с секундами и без. - Выбрасывать класс
Date
. Он плохо спроектирован и давно устарел. Используйте Instant
или другой класс из java .time и сохраните преобразование, которое я делаю в коде.
Ссылки