Я думаю, что вам нужно решить две проблемы здесь:
- как разобрать даты
- как создать собственный десериализатор для вашего JSON
Что касается первой проблемы, вы можете использовать JODA или Java 8. Я остановлюсь на Java 8, потому что новые библиотеки java.time
могут обрабатывать форматы в вашем вопросе.
Что касается JSON, я предлагаю использовать библиотеку Джексона, потому что она чрезвычайно гибкая, и вы можете создавать собственные десериализаторы с ее помощью.
Для импорта библиотеки Джексона вы можете использовать следующие зависимости Maven:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.5</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.5</version>
</dependency>
Десериализатор по умолчанию должен быть упакован в модуль. Вот пример кода десериализатора:
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonTokenId;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.deser.std.StdScalarDeserializer;
import com.fasterxml.jackson.databind.module.SimpleModule;
import java.io.IOException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.ChronoField;
/**
* Used to deserialize LocalTime from a multiple string formats.
*/
public class GenericDateSerializerModule extends SimpleModule {
public static final StdScalarDeserializer<LocalDateTime> DATE_TIME_STD_SCALAR_DESERIALIZER =
new StdScalarDeserializer<LocalDateTime>(LocalDate.class) {
private DateTimeFormatter[] dtfs = {
new DateTimeFormatterBuilder()
.appendPattern("MM/dd/yyyy")
.parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
.parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
.parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0)
.toFormatter(),
DateTimeFormatter.ofPattern("MM/dd/yyyy HH:mm:ss"),
DateTimeFormatter.ofPattern("MM/dd/yyyy hh:mm a")
};
@Override
public LocalDateTime deserialize(JsonParser jsonParser, DeserializationContext deserializationContext)
throws IOException {
if (jsonParser.getCurrentTokenId() == JsonTokenId.ID_STRING) {
String string = jsonParser.getText().trim();
for (DateTimeFormatter dtf : dtfs) {
try {
return LocalDateTime.parse(string, dtf);
} catch(Exception e) {
System.err.println(e);
}
}
}
return null;
}
};
public GenericDateSerializerModule() {
addDeserializer(LocalDateTime.class, DATE_TIME_STD_SCALAR_DESERIALIZER);
}
}
Затем вы можете использовать этот простой модуль с сериализатором для сопоставления JSON с классами:
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.time.LocalDateTime;
class GenericDateSerializerModuleTest {
private ObjectMapper genericDateSerializerMapper = new ObjectMapper();
@BeforeEach
void setUp() {
genericDateSerializerMapper.registerModule(new GenericDateSerializerModule());
}
@Test
void extractMultiFormatDates() throws IOException {
String json = "{\n" +
" \"bookingDate\": \"03/22/1990\",\n" +
" \"createdOn\": \"03/22/1990 12:34:45\",\n" +
" \"modifiedOn\": \"03/22/1990 12:23 AM\"\n" +
"}";
DateJson dateJson = genericDateSerializerMapper.readerFor(DateJson.class).readValue(json);
System.out.println(dateJson);
}
static class DateJson {
private LocalDateTime BookingDate;
private LocalDateTime CreatedOn;
private LocalDateTime ModifiedOn;
public LocalDateTime getBookingDate() {
return BookingDate;
}
public void setBookingDate(LocalDateTime bookingDate) {
BookingDate = bookingDate;
}
public LocalDateTime getCreatedOn() {
return CreatedOn;
}
public void setCreatedOn(LocalDateTime createdOn) {
CreatedOn = createdOn;
}
public LocalDateTime getModifiedOn() {
return ModifiedOn;
}
public void setModifiedOn(LocalDateTime modifiedOn) {
ModifiedOn = modifiedOn;
}
@Override
public String toString() {
return "DateJson{" +
"BookingDate=" + BookingDate +
", CreatedOn=" + CreatedOn +
", ModifiedOn=" + ModifiedOn +
'}';
}
}
}
Если вы запустите этот тест, вы увидите этот вывод на консоли:
java.time.format.DateTimeParseException: Text '03/22/1990 12:34:45' could not be parsed, unparsed text found at index 10
java.time.format.DateTimeParseException: Text '03/22/1990 12:23 AM' could not be parsed, unparsed text found at index 10
java.time.format.DateTimeParseException: Text '03/22/1990 12:23 AM' could not be parsed at index 16
DateJson{BookingDate=1990-03-22T00:00, CreatedOn=1990-03-22T12:34:45, ModifiedOn=1990-03-22T00:23}