82 lines
3.4 KiB
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() + ')';
|
|
}
|
|
}
|
|
}
|