chen.lin
1 天以前 b003a49794f49a329e2702918ecfc8d14b371d0d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
package com.vincent.rsf.server.api.controller.erp.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;
 
/**
 * 支持时间戳(秒/毫秒)与多种字符串格式的 Date 反序列化。
 * 字符串支持:ISO-8601(如 2024-03-03T08:00:00.000+00:00)、yyyy-MM-dd HH:mm:ss,精确到秒。
 */
public class FlexibleDateDeserializer extends JsonDeserializer<Date> {
 
    private static final long TIMESTAMP_MS_THRESHOLD = 10_000_000_000L; // 约 1970-04-26 起为毫秒
 
    private static final String PATTERN_SECONDS = "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 < TIMESTAMP_MS_THRESHOLD ? v * 1000 : v;
            return new Date(ms);
        }
        if (t == JsonToken.VALUE_STRING) {
                String s = p.getText().trim();
                if (s.isEmpty()) {
                    return null;
                }
                // 1) 尝试纯数字字符串(秒或毫秒)
                try {
                    long v = Long.parseLong(s);
                    long ms = v < TIMESTAMP_MS_THRESHOLD ? v * 1000 : v;
                    return new Date(ms);
                } catch (NumberFormatException ignored) {
                }
                // 2) ISO-8601(含 T 和时区)
                if (s.contains("T")) {
                    try {
                        return java.util.Date.from(java.time.Instant.parse(s));
                    } catch (Exception ignored) {
                    }
                }
                // 3) yyyy-MM-dd HH:mm:ss
                try {
                    SimpleDateFormat sdf = new SimpleDateFormat(PATTERN_SECONDS);
                    sdf.setTimeZone(DEFAULT_TZ);
                    sdf.setLenient(false);
                    return sdf.parse(s);
                } catch (Exception ignored) {
                }
                // 4) 仅日期 yyyy-MM-dd
                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);
                    } catch (Exception ignored) {
                    }
                }
                throw new IOException("Cannot parse date: " + s + ", support: timestamp(seconds/ms), ISO-8601, yyyy-MM-dd HH:mm:ss");
        }
        if (t == JsonToken.VALUE_NULL) {
            return null;
        }
        return (Date) ctxt.handleUnexpectedToken(Date.class, p);
    }
}