package com.vincent.rsf.openApi.entity.params; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonToken; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonDeserializer; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.TimeZone; /** * 支持时间戳(秒/毫秒)与字符串 "yyyy-MM-dd HH:mm:ss" 的 Date 反序列化,与 @JsonFormat 配合使用。 */ public class FlexibleDateDeserializer extends JsonDeserializer { private static final long MS_THRESHOLD = 10_000_000_000L; // 大于此为毫秒 private static final String PATTERN = "yyyy-MM-dd HH:mm:ss"; private static final TimeZone DEFAULT_TZ = TimeZone.getTimeZone("GMT+8"); @Override public Date deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { JsonToken t = p.getCurrentToken(); if (t == JsonToken.VALUE_NUMBER_INT || t == JsonToken.VALUE_NUMBER_FLOAT) { long v = p.getLongValue(); long ms = v >= MS_THRESHOLD ? v : v * 1000; return new Date(ms); } if (t == JsonToken.VALUE_STRING) { String s = p.getText().trim(); if (s.isEmpty()) return null; try { long v = Long.parseLong(s); long ms = v >= MS_THRESHOLD ? v : v * 1000; return new Date(ms); } catch (NumberFormatException ignored) { } try { SimpleDateFormat sdf = new SimpleDateFormat(PATTERN); sdf.setTimeZone(DEFAULT_TZ); sdf.setLenient(false); return sdf.parse(s); } catch (Exception ignored) { } if (s.length() >= 10 && s.charAt(4) == '-' && s.charAt(7) == '-') { try { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); sdf.setTimeZone(DEFAULT_TZ); sdf.setLenient(false); return sdf.parse(s.substring(0, 10)); } catch (Exception ignored) { } } return null; } if (t == JsonToken.VALUE_NULL) return null; return (Date) ctxt.handleUnexpectedToken(Date.class, p); } }