在Java开发中,日期时间处理和数据库字段映射是常见的任务,但也容易遇到各种问题,例如:
IllegalArgumentException: Cannot format given Object as a Date(日期格式化失败)Data truncated for column(数据截断错误)本文将通过实际案例,分析这些问题的根本原因,并提供最佳实践解决方案,涵盖:
LocalDateTime vs Date)在导出Excel时,以下代码抛出异常:
row.createCell(15).setCellValue(
order.getProcessTime() != null ?
dateFormat.format(order.getProcessTime()) :
""
);报错信息:
java.lang.IllegalArgumentException: Cannot format given Object as a Date原因是 order.getProcessTime() 返回的是 LocalDateTime,但 dateFormat(SimpleDateFormat)只能处理 java.util.Date 类型。
SimpleDateFormat 仅支持 Date 类型,不能直接格式化 LocalDateTime、Timestamp 等。java.time 包(如 LocalDateTime),但旧代码可能仍依赖 Date。Date 再格式化(兼容旧代码)if (order.getProcessTime() != null) {
Date date = Date.from(
order.getProcessTime().atZone(ZoneId.systemDefault()).toInstant()
);
row.createCell(15).setCellValue(dateFormat.format(date));
} else {
row.createCell(15).setCellValue("");
}DateTimeFormatter(推荐)DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
row.createCell(15).setCellValue(
order.getProcessTime() != null ?
order.getProcessTime().format(formatter) :
""
);public class DateUtils {
private static final DateTimeFormatter DEFAULT_FORMATTER =
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
public static String format(LocalDateTime dateTime) {
return dateTime != null ? dateTime.format(DEFAULT_FORMATTER) : "";
}
}
// 调用
row.createCell(15).setCellValue(DateUtils.format(order.getProcessTime()));插入数据时报错:
(pymysql.err.DataError) (1265, "Data truncated for column 'match_status' at row 1")SQL日志:
INSERT INTO customer_order (..., match_status, ...)
VALUES (..., '待匹配', ...)原因是 match_status 列的长度不足以存储 "待匹配"(3个字符)。
VARCHAR(2) 或 ENUM,但插入了更长的值。VARCHAR(2) 无法存储 "待匹配"(3字符)。ENUM('匹配', '不匹配') 无法接受 "待匹配"。DESCRIBE customer_order;重点关注 match_status 的类型:
如果是 VARCHAR(2),需要扩展长度:
ALTER TABLE customer_order MODIFY COLUMN match_status VARCHAR(10);如果是 ENUM,需要添加选项:
ALTER TABLE customer_order MODIFY COLUMN match_status ENUM('匹配', '待匹配', '不匹配');在Java代码中检查字段长度:
if (order.getMatchStatus().length() > 10) {
throw new IllegalArgumentException("match_status 超出长度限制");
}public class DbUtils {
public static void validateOrder(CustomerOrder order) {
if (order.getMatchStatus() != null && order.getMatchStatus().length() > 10) {
throw new IllegalArgumentException("match_status 超出长度限制");
}
}
}
// 调用
DbUtils.validateOrder(order);
db.insert(order);import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public final class DateUtils {
private static final DateTimeFormatter DEFAULT_FORMATTER =
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
public static String format(LocalDateTime dateTime) {
return dateTime != null ? dateTime.format(DEFAULT_FORMATTER) : "";
}
}public final class DbUtils {
public static void validateOrder(CustomerOrder order) {
// 检查 match_status 长度
if (order.getMatchStatus() != null && order.getMatchStatus().length() > 10) {
throw new IllegalArgumentException("match_status 超出长度限制");
}
// 其他字段校验...
}
}// 1. 校验数据
DbUtils.validateOrder(order);
// 2. 格式化日期
row.createCell(15).setCellValue(DateUtils.format(order.getProcessTime()));
row.createCell(16).setCellValue(DateUtils.format(order.getCreateTime()));
row.createCell(17).setCellValue(DateUtils.format(order.getUpdateTime()));
// 3. 插入数据库
db.insert(order);SimpleDateFormat:线程不安全且仅支持 Date。DateTimeFormatter:支持 LocalDateTime,线程安全。VARCHAR(10) 比 VARCHAR(2) 更灵活。ENUM 约束取值:避免非法数据。通过以上优化,可以彻底解决日期格式化和数据截断问题,提升代码健壮性!