Java日期格式化之IllegalArgumentException與MySQL數(shù)據(jù)截?cái)鄦栴}解決
引言
在Java開發(fā)中,日期時(shí)間處理和數(shù)據(jù)庫字段映射是常見的任務(wù),但也容易遇到各種問題,例如:
IllegalArgumentException: Cannot format given Object as a Date(日期格式化失?。?/li>- MySQL
Data truncated for column(數(shù)據(jù)截?cái)噱e(cuò)誤)
本文將通過實(shí)際案例,分析這些問題的根本原因,并提供最佳實(shí)踐解決方案,涵蓋:
- Java日期時(shí)間格式化問題(
LocalDateTimevsDate) - MySQL字段長度與數(shù)據(jù)截?cái)鄦栴}
- 代碼優(yōu)化與統(tǒng)一處理方案
一、Java日期格式化問題:IllegalArgumentException
1.1 問題現(xiàn)象
在導(dǎo)出Excel時(shí),以下代碼拋出異常:
row.createCell(15).setCellValue(
order.getProcessTime() != null ?
dateFormat.format(order.getProcessTime()) :
""
);
報(bào)錯(cuò)信息:
java.lang.IllegalArgumentException: Cannot format given Object as a Date
原因是 order.getProcessTime() 返回的是 LocalDateTime,但 dateFormat(SimpleDateFormat)只能處理 java.util.Date 類型。
1.2 根本原因
SimpleDateFormat僅支持Date類型,不能直接格式化LocalDateTime、Timestamp等。- Java 8+ 推薦使用
java.time包(如LocalDateTime),但舊代碼可能仍依賴Date。
1.3 解決方案
方案1:轉(zhuǎn)換為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:提取工具類(統(tǒng)一處理)
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) : "";
}
}
// 調(diào)用
row.createCell(15).setCellValue(DateUtils.format(order.getProcessTime()));
二、MySQL數(shù)據(jù)截?cái)鄦栴}:Data truncated for column
2.1 問題現(xiàn)象
插入數(shù)據(jù)時(shí)報(bào)錯(cuò):
(pymysql.err.DataError) (1265, "Data truncated for column 'match_status' at row 1")
SQL日志:
INSERT INTO customer_order (..., match_status, ...) VALUES (..., '待匹配', ...)
原因是 match_status 列的長度不足以存儲(chǔ) "待匹配"(3個(gè)字符)。
2.2 根本原因
MySQL字段定義可能是 VARCHAR(2) 或 ENUM,但插入了更長的值。
例如:
VARCHAR(2)無法存儲(chǔ)"待匹配"(3字符)。ENUM('匹配', '不匹配')無法接受"待匹配"。
2.3 解決方案
步驟1:檢查表結(jié)構(gòu)
DESCRIBE customer_order;
重點(diǎn)關(guān)注 match_status 的類型:
如果是 VARCHAR(2),需要擴(kuò)展長度:
ALTER TABLE customer_order MODIFY COLUMN match_status VARCHAR(10);
如果是 ENUM,需要添加選項(xiàng):
ALTER TABLE customer_order MODIFY COLUMN match_status ENUM('匹配', '待匹配', '不匹配');
步驟2:驗(yàn)證數(shù)據(jù)長度
在Java代碼中檢查字段長度:
if (order.getMatchStatus().length() > 10) {
throw new IllegalArgumentException("match_status 超出長度限制");
}
步驟3:統(tǒng)一處理(推薦)
public class DbUtils {
public static void validateOrder(CustomerOrder order) {
if (order.getMatchStatus() != null && order.getMatchStatus().length() > 10) {
throw new IllegalArgumentException("match_status 超出長度限制");
}
}
}
// 調(diào)用
DbUtils.validateOrder(order);
db.insert(order);
三、完整優(yōu)化代碼示例
3.1 日期時(shí)間格式化工具類
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 數(shù)據(jù)庫字段校驗(yàn)工具類
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 超出長度限制");
}
// 其他字段校驗(yàn)...
}
}
3.3 統(tǒng)一調(diào)用示例
// 1. 校驗(yàn)數(shù)據(jù) 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. 插入數(shù)據(jù)庫 db.insert(order);
四、總結(jié)與最佳實(shí)踐
4.1 日期時(shí)間處理
- 避免使用
SimpleDateFormat:線程不安全且僅支持Date。 - 推薦
DateTimeFormatter:支持LocalDateTime,線程安全。 - 提取工具類:統(tǒng)一格式化邏輯。
4.2 MySQL字段設(shè)計(jì)
- 提前規(guī)劃字段長度:例如
VARCHAR(10)比VARCHAR(2)更靈活。 - 使用
ENUM約束取值:避免非法數(shù)據(jù)。 - 代碼校驗(yàn)數(shù)據(jù)長度:提前攔截問題。
4.3 統(tǒng)一處理原則
- 減少重復(fù)代碼:通過工具類復(fù)用邏輯。
- 提前校驗(yàn):在插入數(shù)據(jù)庫前檢查數(shù)據(jù)合法性。
通過以上優(yōu)化,可以徹底解決日期格式化和數(shù)據(jù)截?cái)鄦栴},提升代碼健壯性!
到此這篇關(guān)于Java日期格式化之IllegalArgumentException與MySQL數(shù)據(jù)截?cái)鄦栴}解決的文章就介紹到這了,更多相關(guān)Java日期格式化內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
解析Linux系統(tǒng)中JVM內(nèi)存2GB上限的詳解
本篇文章是對Linux系統(tǒng)中JVM內(nèi)存2GB上限進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05
Mybatis流式查詢并實(shí)現(xiàn)將結(jié)果分批寫入文件
這篇文章主要介紹了Mybatis流式查詢并實(shí)現(xiàn)將結(jié)果分批寫入文件方式,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-08-08
IDEA使用maven創(chuàng)建hibernate項(xiàng)目的實(shí)現(xiàn)步驟(圖文)
本文主要介紹了IDEA使用maven創(chuàng)建hibernate項(xiàng)目的實(shí)現(xiàn)步驟,包括創(chuàng)建Maven項(xiàng)目,配置Hibernate,以及創(chuàng)建實(shí)體類映射到數(shù)據(jù)庫等步驟,具有一定的參考價(jià)值,感興趣的可以了解一下2023-08-08
解決springboot啟動(dòng)時(shí)報(bào)錯(cuò)的問題ApplicationEventMulticaster not&nbs
這篇文章主要介紹了解決springboot啟動(dòng)時(shí)報(bào)錯(cuò)的問題ApplicationEventMulticaster not initialized,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2025-06-06
Java中關(guān)于ThreadLocal的隱式引用詳解
這篇文章主要介紹了Java中關(guān)于ThreadLocal的隱式引用,從線程的角度看,每個(gè)線程都保持一個(gè)對其線程局部變量副本的隱式引用,只要線程是活動(dòng)的,ThreadLocal實(shí)例就是可訪問的,下面我們來具體看看2024-03-03

