You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot Batch中CSV转H2库时LocalDateTime格式转换异常问题

问题:Spring Boot Batch CSV时间格式转换保留日期部分报错

使用Spring Boot Batch读取CSV文件并写入H2数据库时,CSV内时间格式为2000-08-15 19:07:46,希望仅保留日期部分2000-08-15。但将localDateTimeFormat方法中的DateTimeFormatter格式改为yyyy-MM-dd时,出现DateTimeParseException错误,提示无法解析含时间的文本。

错误信息

java.time.format.DateTimeParseException: Text '1999-01-25 13:08:57' could not be parsed, unparsed text found at index 10
    at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2109) ~[na:na]
    at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:2008) ~[na:na]
    at java.base/java.time.LocalDateTime.parse(LocalDateTime.java:494) ~[na:na]
    at com.example.batchprocessingcsvtodatabase.config.UserProcessor.localDateTimeFormat(UserProcessor.java:37) ~[classes/:na]
    at com.example.batchprocessingcsvtodatabase.config.UserProcessor.process(UserProcessor.java:26) ~[classes/:na]
    at com.example.batchprocessingcsvtodatabase.config.UserProcessor.process(UserProcessor.java:14) ~[classes/:na]

User实体类

public class User extends BaseEntity{

    @Type(type = "org.hibernate.type.UUIDCharType")
    private UUID personId;

    private String firstName;
    private String lastName;
    private String email;

    @Enumerated(EnumType.STRING)
    private Gender gender;

    private String country;

    @JsonFormat(pattern="yyyy-MM-dd")
    private LocalDateTime birthday;

    private int age;
}

UserProcessor处理器类

public class UserProcessor implements ItemProcessor<UserInput, User> {


    @Override
    public User process(UserInput userInput) throws Exception {

        User user = User.builder()
                .personId(UUID.fromString(userInput.getPersonId()))
                .firstName(userInput.getFirstName())
                .lastName(userInput.getLastName())
                .email(userInput.getEmail())
                .country(userInput.getCountry())
                .birthday(localDateTimeFormat(userInput.getBirthday()))
                .gender(userInput.getGender().equals("Male") ? Gender.MALE : Gender.FEMALE)
                .age(Period.between(localDateTimeFormat(userInput.getBirthday()).toLocalDate(), LocalDate.now()).getYears())
                .build();

        return user;
    }

    private LocalDateTime localDateTimeFormat(String birthday) {

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime formatDateTime = LocalDateTime.parse(birthday, formatter);

        return formatDateTime;
    }
}

解决办法

核心原因

报错是因为用yyyy-MM-dd格式去解析包含时分秒的完整时间字符串,格式不匹配导致解析失败。必须先按CSV的原始格式解析,再处理日期部分。

方案1:解析完整时间后截断日期(保留LocalDateTime类型)

修改localDateTimeFormat方法,先解析完整时间,再将时分秒设为0:

private LocalDateTime localDateTimeFormat(String birthday) {
    // 按CSV原始格式解析完整时间
    DateTimeFormatter fullFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    LocalDateTime fullDateTime = LocalDateTime.parse(birthday, fullFormatter);
    // 保留日期部分,时分秒置为00:00:00
    return fullDateTime.with(LocalTime.MIN);
}

方案2:截取日期字符串再解析(更高效)

直接截取原始字符串的前10位(日期部分),再解析为LocalDateTime:

private LocalDateTime localDateTimeFormat(String birthday) {
    // 截取前10位日期字符串
    String datePart = birthday.substring(0, 10);
    DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    // 解析为LocalDate后转成LocalDateTime(时分秒默认0)
    return LocalDate.parse(datePart, dateFormatter).atStartOfDay();
}

优化建议:字段类型替换为LocalDate

如果业务中只需要日期,建议将实体类的birthday字段改为LocalDate类型,更贴合业务语义,简化后续处理:

// 替换原LocalDateTime字段
@JsonFormat(pattern="yyyy-MM-dd")
private LocalDate birthday;

对应的处理器方法修改为返回LocalDate:

private LocalDate localDateFormat(String birthday) {
    DateTimeFormatter fullFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    return LocalDateTime.parse(birthday, fullFormatter).toLocalDate();
}

计算年龄的代码也可以简化:

.age(Period.between(localDateFormat(userInput.getBirthday()), LocalDate.now()).getYears())

内容的提问来源于stack exchange,提问作者Sercan Noyan Germiyanoğlu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 07:35:24