Java日期格式化之IllegalArgumentException与MySQL数据截断问题解决

 更新时间:2025年07月07日 10:02:00   作者:码农阿豪@新空间  
在Java开发中,日期时间处理和数据库字段映射是常见的任务,但也容易遇到各种问题,譬如IllegalArgumentException与MySQL数据截断问题,下面我们就来看看他们的具体解决方法吧

引言

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

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

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

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

一、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 统一处理原则

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

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

到此这篇关于Java日期格式化之IllegalArgumentException与MySQL数据截断问题解决的文章就介绍到这了,更多相关Java日期格式化内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 解析Linux系统中JVM内存2GB上限的详解

    解析Linux系统中JVM内存2GB上限的详解

    本篇文章是对Linux系统中JVM内存2GB上限进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • 学习Java多线程之volatile域

    学习Java多线程之volatile域

    这篇文章主要为大家详细介绍了Java多线程之volatile域,Java 语言提供了一种稍弱的同步机制,即volatile,本文为大家解答,感兴趣的小伙伴们可以参考一下
    2016-02-02
  • java中通过行为参数化传递代码方案

    java中通过行为参数化传递代码方案

    大家好,本篇文章主要讲的是java中通过行为参数化传递代码方案,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下
    2022-02-02
  • Mybatis流式查询并实现将结果分批写入文件

    Mybatis流式查询并实现将结果分批写入文件

    这篇文章主要介绍了Mybatis流式查询并实现将结果分批写入文件方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-08-08
  • IDEA使用maven创建hibernate项目的实现步骤(图文)

    IDEA使用maven创建hibernate项目的实现步骤(图文)

    本文主要介绍了IDEA使用maven创建hibernate项目的实现步骤,包括创建Maven项目,配置Hibernate,以及创建实体类映射到数据库等步骤,具有一定的参考价值,感兴趣的可以了解一下
    2023-08-08
  • 解决springboot启动时报错的问题ApplicationEventMulticaster not initialized

    解决springboot启动时报错的问题ApplicationEventMulticaster not&nbs

    这篇文章主要介绍了解决springboot启动时报错的问题ApplicationEventMulticaster not initialized,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-06-06
  • Spring Retry重试框架的使用讲解

    Spring Retry重试框架的使用讲解

    重试的使用场景比较多,比如调用远程服务时,由于网络或者服务端响应慢导致调用超时,此时可以多重试几次。用定时任务也可以实现重试的效果,但比较麻烦,用Spring Retry的话一个注解搞定所有,感兴趣的可以了解一下
    2023-01-01
  • JDK的Parser来解析Java源代码详解

    JDK的Parser来解析Java源代码详解

    这篇文章主要介绍了JDK的Parser来解析Java源代码的相关资料,需要的朋友可以参考下
    2016-09-09
  • Java中关于ThreadLocal的隐式引用详解

    Java中关于ThreadLocal的隐式引用详解

    这篇文章主要介绍了Java中关于ThreadLocal的隐式引用,从线程的角度看,每个线程都保持一个对其线程局部变量副本的隐式引用,只要线程是活动的,ThreadLocal实例就是可访问的,下面我们来具体看看
    2024-03-03
  • 日历显示读出输入的年月的java代码

    日历显示读出输入的年月的java代码

    这篇文章主要介绍了日历显示读出输入的年月的java代码,有需要的朋友可以参考一下
    2013-12-12

最新评论