java-commons/commons-serialize-databind/src/main/java/io/gitlab/jfronny/commons/serialize/databind/impl/adapter/DefaultDateTypeAdapter.java

82 lines
3.4 KiB
Java

package io.gitlab.jfronny.commons.serialize.databind.impl.adapter;
import io.gitlab.jfronny.commons.serialize.databind.api.SerializerFor;
import io.gitlab.jfronny.commons.serialize.databind.api.TypeAdapter;
import io.gitlab.jfronny.commons.serialize.ISO8601Utils;
import io.gitlab.jfronny.commons.serialize.databind.impl.PreJava9DateFormatProvider;
import io.gitlab.jfronny.commons.serialize.MalformedDataException;
import io.gitlab.jfronny.commons.serialize.SerializeReader;
import io.gitlab.jfronny.commons.serialize.SerializeWriter;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.*;
@SerializerFor(targets = Date.class)
public class DefaultDateTypeAdapter extends TypeAdapter<Date> {
private static final String SIMPLE_NAME = "DefaultDateTypeAdapter";
/**
* List of 1 or more different date formats used for de-serialization attempts. The first of them
* is used for serialization as well.
*/
private final List<DateFormat> dateFormats = new ArrayList<>();
public DefaultDateTypeAdapter() {
dateFormats.add(DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT, Locale.US));
if (!Locale.getDefault().equals(Locale.US)) {
dateFormats.add(DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT));
}
dateFormats.add(PreJava9DateFormatProvider.getUsDateTimeFormat(DateFormat.DEFAULT, DateFormat.DEFAULT));
}
@Override
public <TEx extends Exception, Writer extends SerializeWriter<TEx, Writer>> void serialize(Date value, Writer writer) throws TEx, MalformedDataException {
DateFormat dateFormat = dateFormats.getFirst();
String dateFormatAsString;
// Needs to be synchronized since JDK DateFormat classes are not thread-safe
synchronized (dateFormats) {
dateFormatAsString = dateFormat.format(value);
}
writer.value(dateFormatAsString);
}
@Override
public <TEx extends Exception, Reader extends SerializeReader<TEx, Reader>> Date deserialize(Reader reader) throws TEx, MalformedDataException {
String s = reader.nextString();
// Needs to be synchronized since JDK DateFormat classes are not thread-safe
synchronized (dateFormats) {
for (DateFormat dateFormat : dateFormats) {
TimeZone originalTimeZone = dateFormat.getTimeZone();
try {
return dateFormat.parse(s);
} catch (ParseException ignored) {
// OK: try the next format
} finally {
dateFormat.setTimeZone(originalTimeZone);
}
}
}
try {
return ISO8601Utils.parse(s, new ParsePosition(0));
} catch (ParseException e) {
throw new MalformedDataException(
"Failed parsing '" + s + "' as Date; at path " + reader.getPreviousPath(), e);
}
}
@Override
public String toString() {
DateFormat defaultFormat = dateFormats.getFirst();
if (defaultFormat instanceof SimpleDateFormat) {
return SIMPLE_NAME + '(' + ((SimpleDateFormat) defaultFormat).toPattern() + ')';
} else {
return SIMPLE_NAME + '(' + defaultFormat.getClass().getSimpleName() + ')';
}
}
}