使用Apache Commons CSV的CSVFormat解析日期时间格式失败
问题解决:Apache Commons CSV 日期格式化无效的问题
核心问题分析
你注释掉的代码存在两个致命错误:
- 类型不匹配:
CSVFormat调用format()方法返回的是String类型,但你试图赋值给CSVFormat变量,直接导致编译失败。 - 方法误用:
CSVFormat的format()方法是用来将CSV记录格式化为字符串的工具方法,根本不是用来配置日期格式的——Apache Commons CSV本身没有全局设置日期格式的功能,它只负责按CSV规则输出你传入的原始数据。
你的getRecordData方法返回的是List<String>,说明日期字段已经被转成了默认格式的字符串,CSVPrinter只会直接输出这些字符串,不会做二次格式化。
解决方案:提前格式化日期字段
要实现自定义日期格式,你需要在将日期数据转为字符串的阶段(也就是getRecordData方法内部)做格式化处理,而非在CSVFormat中配置。
示例代码(Java 8+ 日期类型)
假设你的实体类中日期字段是LocalDateTime或Timestamp类型,修改getRecordData方法的日期处理逻辑:
import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.sql.Timestamp; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.List; // 定义你需要的日期格式,对应期望的"MM-dd-yyyy HH:mm:ss.SSSSSS" private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("MM-dd-yyyy HH:mm:ss.SSSSSS"); private List<String> getRecordData(Object objectClass) throws InstantiationException, IllegalAccessException { List<String> data = new ArrayList<>(); // 遍历实体类字段 for (Field field : objectClass.getClass().getDeclaredFields()) { field.setAccessible(true); Object value = field.get(objectClass); if (value instanceof LocalDateTime) { // 格式化LocalDateTime类型 data.add(DATE_FORMATTER.format((LocalDateTime) value)); } else if (value instanceof Timestamp) { // 格式化Timestamp类型(转为LocalDateTime处理) data.add(DATE_FORMATTER.format(((Timestamp) value).toLocalDateTime())); } else { // 其他类型直接转字符串 data.add(value != null ? value.toString() : ""); } } return data; }
旧版Date类型处理方案
如果你的字段是java.util.Date,可以用SimpleDateFormat:
import java.text.SimpleDateFormat; import java.util.Date; private static final SimpleDateFormat DATE_FORMATTER = new SimpleDateFormat("MM-dd-yyyy HH:mm:ss.SSSSSS"); // 在getRecordData中添加: if (value instanceof Date) { data.add(DATE_FORMATTER.format((Date) value)); }
验证修改后的CSV生成逻辑
你的dataToCSV方法不需要调整CSVFormat,保持原有逻辑即可:
public ByteArrayInputStream dataToCSV(List<?> dataList, char delimiter){ final CSVFormat format = CSVFormat.DEFAULT.withDelimiter(delimiter); try (ByteArrayOutputStream out = new ByteArrayOutputStream(); CSVPrinter csvPrinter = new CSVPrinter(new PrintWriter(out), format);) { if (!dataList.isEmpty()){ csvPrinter.printRecord(this.getHeaders(dataList.get(0))); for (Object objectClass : dataList) { List<String> data = getRecordData(objectClass); csvPrinter.printRecord(data); } } csvPrinter.flush(); return new ByteArrayInputStream(out.toByteArray()); } catch (Exception e) { throw new RuntimeException(e); } }
关键注意事项
- 日期格式符区分大小写:
yyyy是4位年份,MM是月份,dd是日期,ss是秒,SSSSSS是微秒(对应数据库中的123456部分),不要写成大写的YYYY或SS(大写SS代表毫秒)。 - Commons CSV仅负责处理CSV的结构(分隔符、引号、换行等),不负责数据内容的格式化,所有内容格式化需提前完成。
内容的提问来源于stack exchange,提问作者Moaaz Gaballah
相关产品推荐
相关产品推荐

