> 技术文档 > Java日期格式化最佳实践:解决IllegalArgumentException与MySQL数据截断问题

Java日期格式化最佳实践:解决IllegalArgumentException与MySQL数据截断问题


个人名片
在这里插入图片描述
🎓作者简介:java领域优质创作者
🌐个人主页:码农阿豪
📞工作室:新空间代码工作室(提供各种软件服务)
💌个人邮箱:[2435024119@qq.com]
📱个人微信:15279484656
🌐个人导航网站:www.forff.top
💡座右铭:总有人要赢。为什么不能是我呢?

  • 专栏导航:

码农阿豪系列专栏导航
面试专栏:收集了java相关高频面试题,面试实战总结🍻🎉🖥️
Spring5系列专栏:整理了Spring5重要知识点与实战演练,有案例可直接使用🚀🔧💻
Redis专栏:Redis从零到一学习分享,经验总结,案例实战💐📝💡
全栈系列专栏:海纳百川有容乃大,可能你想要的东西里面都有🤸🌱🚀

目录

  • Java日期格式化最佳实践:解决IllegalArgumentException与MySQL数据截断问题
    • 引言
    • 一、Java日期格式化问题:IllegalArgumentException
      • 1.1 问题现象
      • 1.2 根本原因
      • 1.3 解决方案
        • 方案1:转换为 `Date` 再格式化(兼容旧代码)
        • 方案2:直接使用 `DateTimeFormatter`(推荐)
        • 方案3:提取工具类(统一处理)
    • 二、MySQL数据截断问题:Data truncated for column
      • 2.1 问题现象
      • 2.2 根本原因
      • 2.3 解决方案
        • 步骤1:检查表结构
        • 步骤2:验证数据长度
        • 步骤3:统一处理(推荐)
    • 三、完整优化代码示例
      • 3.1 日期时间格式化工具类
      • 3.2 数据库字段校验工具类
      • 3.3 统一调用示例
    • 四、总结与最佳实践
      • 4.1 日期时间处理
      • 4.2 MySQL字段设计
      • 4.3 统一处理原则

Java日期格式化最佳实践:解决IllegalArgumentException与MySQL数据截断问题

引言

在Java开发中,日期时间处理和数据库字段映射是常见的任务,但也容易遇到各种问题,例如:

  • IllegalArgumentException: Cannot format given Object as a Date(日期格式化失败)
  • MySQL Data truncated for column(数据截断错误)

本文将通过实际案例,分析这些问题的根本原因,并提供最佳实践解决方案,涵盖:

  1. Java日期时间格式化问题(LocalDateTime vs Date
  2. MySQL字段长度与数据截断问题
  3. 代码优化与统一处理方案

一、Java日期格式化问题:IllegalArgumentException

1.1 问题现象

在导出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,但 dateFormatSimpleDateFormat)只能处理 java.util.Date 类型。

1.2 根本原因

  • SimpleDateFormat 仅支持 Date 类型,不能直接格式化 LocalDateTimeTimestamp 等。
  • Java 8+ 推荐使用 java.time 包(如 LocalDateTime),但旧代码可能仍依赖 Date

1.3 解决方案

方案1:转换为 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(\"\");}
方案2:直接使用 DateTimeFormatter(推荐)
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(\"yyyy-MM-dd HH:mm:ss\");row.createCell(15).setCellValue( order.getProcessTime() != null ? order.getProcessTime().format(formatter) : \"\");
方案3:提取工具类(统一处理)
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()));

二、MySQL数据截断问题:Data truncated for column

2.1 问题现象

插入数据时报错:

(pymysql.err.DataError) (1265, \"Data truncated for column \'match_status\' at row 1\")

SQL日志:

INSERT INTO customer_order (..., match_status, ...) VALUES (..., \'待匹配\', ...)

原因是 match_status 列的长度不足以存储 \"待匹配\"(3个字符)。

2.2 根本原因

  • MySQL字段定义可能是 VARCHAR(2)ENUM,但插入了更长的值。
  • 例如:
    • VARCHAR(2) 无法存储 \"待匹配\"(3字符)。
    • ENUM(\'匹配\', \'不匹配\') 无法接受 \"待匹配\"

2.3 解决方案

步骤1:检查表结构
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(\'匹配\', \'待匹配\', \'不匹配\');
步骤2:验证数据长度

在Java代码中检查字段长度:

if (order.getMatchStatus().length() > 10) { throw new IllegalArgumentException(\"match_status 超出长度限制\");}
步骤3:统一处理(推荐)
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);

三、完整优化代码示例

3.1 日期时间格式化工具类

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) : \"\"; }}

3.2 数据库字段校验工具类

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 超出长度限制\"); } // 其他字段校验... }}

3.3 统一调用示例

// 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);

四、总结与最佳实践

4.1 日期时间处理

  • 避免使用 SimpleDateFormat:线程不安全且仅支持 Date
  • 推荐 DateTimeFormatter:支持 LocalDateTime,线程安全。
  • 提取工具类:统一格式化逻辑。

4.2 MySQL字段设计

  • 提前规划字段长度:例如 VARCHAR(10)VARCHAR(2) 更灵活。
  • 使用 ENUM 约束取值:避免非法数据。
  • 代码校验数据长度:提前拦截问题。

4.3 统一处理原则

  • 减少重复代码:通过工具类复用逻辑。
  • 提前校验:在插入数据库前检查数据合法性。

通过以上优化,可以彻底解决日期格式化和数据截断问题,提升代码健壮性!