修复bug

This commit is contained in:
zhoupeng committed 2026-09-05 17:39:15 +08:00
1 parent 2c10db5b24
commit e046c67f64
1 file changed
+55 -2
@@ -1,27 +1,80 @@
package cn.iocoder.yudao.framework.common.util.json.databind;
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.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
/**
* 基于时间戳的 LocalDateTime 反序列化器
*
* 支持两种 JSON 写法:
* 1. 时间戳:13 位毫秒(yudao 前端默认),兼容 10 位秒级时间戳
* 2. 日期字符串:"yyyy-MM-dd HH:mm:ss"、"yyyy-MM-dd"、ISO-8601("yyyy-MM-dd'T'HH:mm:ss")
*
* 注意:原实现直接 {@code p.getValueAsLong()},传入 "yyyy-MM-dd HH:mm:ss" 字符串时
* 会静默解析失败并返回 0,导致入库时间变成 1970-01-01 08:00:00(东八区 epoch 0)。
*
* @author 老五
*/
public class TimestampLocalDateTimeDeserializer extends JsonDeserializer<LocalDateTime> {
public static final TimestampLocalDateTimeDeserializer INSTANCE = new TimestampLocalDateTimeDeserializer();
private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
@Override
public LocalDateTime deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
// 将 Long 时间戳,转换为 LocalDateTime 对象
return LocalDateTime.ofInstant(Instant.ofEpochMilli(p.getValueAsLong()), ZoneId.systemDefault());
// 1. 数字:直接按毫秒时间戳处理(与原行为一致)
if (p.getCurrentToken() == JsonToken.VALUE_NUMBER_INT) {
return LocalDateTime.ofInstant(Instant.ofEpochMilli(p.getLongValue()), ZoneId.systemDefault());
}
// 2. 字符串:先尝试时间戳,再尝试常见日期格式
String text = p.getValueAsString();
if (text == null) {
return null;
}
text = text.trim();
if (text.isEmpty()) {
return null;
}
// 2.1 纯数字:13 位毫秒、10 位秒
if (text.matches("\\d+")) {
long timestamp = Long.parseLong(text);
if (text.length() <= 10) { // 秒级时间戳,转毫秒
timestamp *= 1000;
}
return LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp), ZoneId.systemDefault());
}
// 2.2 "yyyy-MM-dd HH:mm:ss"
try {
return LocalDateTime.parse(text, DATE_TIME_FORMATTER);
} catch (Exception ignore) {
// 继续尝试其它格式
}
// 2.3 "yyyy-MM-dd"(按当天 00:00:00)
try {
return LocalDate.parse(text, DATE_FORMATTER).atStartOfDay();
} catch (Exception ignore) {
// 继续尝试 ISO 格式
}
// 2.4 ISO-8601:"yyyy-MM-dd'T'HH:mm:ss"
try {
return LocalDateTime.parse(text);
} catch (Exception ignore) {
// 落到最后的报错
}
throw ctxt.weirdStringException(text, LocalDateTime.class,
"Expected timestamp (millis or seconds) or date string (yyyy-MM-dd HH:mm:ss)");
}
}