Ở đây bạn đi, tùy chỉnh Gson builder mà xử lý hầu hết các ngày mẫu sử dụng JodaTime (có thể loại trừ nó nếu không muốn sử dụng nó, nó chỉ mở rộng khả năng)
public class MyGsonBuilder {
public static <T> List<T> toList(String json, Class<T> clazz) {
if (null == json) {
return null;
}
Gson gson = build();
return gson.fromJson(json, new TypeToken<T>() {
}.getType());
}
private static boolean enableLog = false;
private static void log(String log) {
if (enableLog) Log.d("DEBUG_GSON_TIME", log);
}
static List<SimpleDateFormat> knownPatterns = new ArrayList<>(Arrays.asList(
new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"),
new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ"),
new SimpleDateFormat("yyyy-MM-dd' 'HH:mm:ss"),
new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"),
new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss")
));
static JsonSerializer<Date> ser = new JsonSerializer<Date>() {
@Override
public JsonElement serialize(Date src, Type typeOfSrc, JsonSerializationContext context) {
return new GsonBuilder().create().toJsonTree(buildIso8601Format().format(src));
}
};
static JsonDeserializer<Date> deser = new JsonDeserializer<Date>() {
@Override
public Date deserialize(JsonElement json, Type typeOfT,
JsonDeserializationContext context) throws JsonParseException {
Date date = null;
try {
// Take a try
String dateString = json.getAsJsonPrimitive().getAsString();
log("deserialize date string = " + dateString);
date = buildOddFormat().parse(dateString);
log(" pattern (yyyy-MM-dd HH:mm:ss) = SUCCESS " + dateString + " = " + date.toString());
} catch (Throwable t) {
// Loop on
log(" pattern (yyyy-MM-dd HH:mm:ss) = error = " + t.getMessage());
}
if (date == null) {
try {
// Take a try
String dateString = json.getAsJsonPrimitive().getAsString();
date = buildOldFormat().parse(dateString);
log(" pattern (MMM dd, yyyy HH:mm:ss) = SUCCESS " + dateString + " = " + date.toString());
} catch (Throwable t) {
// Loop on
log(" pattern (MMM dd, yyyy HH:mm:ss) = error = " + t.getMessage());
}
}
if (date == null) {
try {
// Take a try
String dateString = json.getAsJsonPrimitive().getAsString();
date = buildVeryOldFormat().parse(dateString);
log(" pattern (MMM d, yyyy HH:mm:ss) = SUCCESS " + dateString + " = " + date.toString());
} catch (Throwable t) {
// Loop on
log(" pattern (MMM d, yyyy HH:mm:ss) = error = " + t.getMessage());
}
}
if (date == null)
for (SimpleDateFormat pattern : knownPatterns) {
try {
// Take a try
if (!pattern.toPattern().contains("Z"))
pattern.setTimeZone(TimeZone.getTimeZone("UTC"));
String dateString = json.getAsJsonPrimitive().getAsString();
if (!pattern.toPattern().contains("Z"))
pattern.setTimeZone(TimeZone.getTimeZone("UTC"));
date = new Date(pattern.parse(dateString).getTime());
log(" pattern (" + pattern.toPattern() + ") = SUCCESS " + dateString + " = " + date.toString());
break;
} catch (Throwable t) {
// Loop on
log(" pattern (" + pattern.toPattern() + ") = error = " + t.getMessage());
}
}
// }
if (date == null) {
try {
date = new Date(json.getAsJsonPrimitive().getAsLong());
log(" Joda = SUCCESS " + json.getAsJsonPrimitive().getAsString() + " = " + date.toString());
} catch (Throwable t) {
log(" pattern (Long) = error = " + t.getMessage());
}
}
if (date == null) {
try {
date = DateFormat.getInstance().parse(json.getAsJsonPrimitive().getAsString());
log(" Joda = SUCCESS " + json.getAsJsonPrimitive().getAsString() + " = " + date.toString());
} catch (Throwable t) {
log(" pattern (DateFormat.getInstance().parse()) = error = " + t.getMessage());
}
}
if (date == null) {
DateTimeFormatter fmt = ISODateTimeFormat.dateTime();
try {
String dateString = json.getAsJsonPrimitive().getAsString();
date = fmt.parseDateTime(dateString).toDate();
log(" Joda = SUCCESS " + dateString + " = " + date.toString());
} catch (Throwable t) {
// Loop on
log(" Joda error = " + t.getMessage());
Crashlytics.logException(new Throwable("NON PARSABLE DATE!!! = " + json.toString()));
}
}
if (date == null)
date = new Date();
return date;
}
};
private static DateFormat buildIso8601Format() {
DateFormat iso8601Format = new SimpleDateFormat(
"yyyy-MM-dd'T'HH:mm:ss.SSSZ");
return iso8601Format;
}
private static DateFormat buildOddFormat() {
DateFormat iso8601Format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
iso8601Format.setTimeZone(TimeZone.getTimeZone("UTC"));
return iso8601Format;
}
private static DateFormat buildOldFormat() {
DateFormat iso8601Format = new SimpleDateFormat("MMM dd, yyyy HH:mm:ss");
iso8601Format.setTimeZone(TimeZone.getTimeZone("UTC"));
return iso8601Format;
}
private static DateFormat buildVeryOldFormat() {
DateFormat iso8601Format = new SimpleDateFormat("MMM d, yyyy HH:mm:ss");
iso8601Format.setTimeZone(TimeZone.getTimeZone("UTC"));
return iso8601Format;
}
static public Gson build() {
Gson gson = new GsonBuilder()
//.setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ")
.registerTypeAdapter(Date.class, deser)
.registerTypeAdapter(Date.class, ser)
.excludeFieldsWithoutExposeAnnotation()
.create();
return gson;
}
}
Nguồn
2017-05-19 11:10:54
chữ 'z' nhỏ ở cuối có thể là vấn đề đối với chuỗi ngày tháng được định dạng ISO vì múi giờ có thể là Z hoặc số 00: 00 không thể được xử lý đúng cách bởi SimpleDateFormat – Lucas
Rất muốn biết cách định cấu hình Spring để thực hiện việc này. – user1944491
câu trả lời hoàn hảo ..... đã bỏ phiếu cho 1 – sonida