Kotlin中CSV日期转LocalDate失败:@CsvDate格式匹配问题
解决opencsv解析英文全称星期日期的DateTimeParseException问题
问题场景
使用Kotlin结合opencsv解析CSV时,需将格式为"Thursday, October 24, 2019"(星期全称, 月份全称 日, 年)的日期字符串解析为LocalDate类型。在实体类字段上使用@CsvDate(value = "E, MMMM d, yyyy")注解匹配格式,却抛出DateTimeParseException,报错信息显示:
Text 'Thursday, October 24, 2019' could not be parsed at index 3
相关代码如下:
实体类代码
@Entity @Data @Getter @Setter @ToString @Table(name="used_vacation") data class UsedVacation( @Id @GeneratedValue(strategy = GenerationType.IDENTITY) val id:Long, @Column(name="date_start") @CsvDate(value = "E, MMMM d, yyyy") @CsvBindByPosition(position = 1) val dateStart:LocalDate, @Column(name="date_end") @CsvDate(value = "E, MMMM d, yyyy") @CsvBindByPosition(position = 2) val dateEnd:LocalDate, @ManyToOne @JoinColumn(name="employee_id",nullable=false) @CsvBindByPosition(position = 0) val employee:Employee, )
CSV解析方法
private fun createCSVToBeanUsedVacation(fileReader: BufferedReader?): CsvToBean<UsedVacation> = CsvToBeanBuilder<UsedVacation>(fileReader) .withType(UsedVacation::class.java) .withSkipLines(2) .withIgnoreLeadingWhiteSpace(true) .build()
问题原因
- 日期格式符错误:
E是Java DateTimeFormatter中的星期缩写模式(如Thu),而CSV中的星期是完整名称(如Thursday),需要用EEEE模式匹配全称星期。 - 区域设置缺失:若系统默认区域非英文,opencsv解析月份、星期全称时会因语言不匹配失败。
解决方案
1. 修改@CsvDate的格式字符串
将注解中的格式改为"EEEE, MMMM d, yyyy",匹配完整星期名称:
@CsvDate(value = "EEEE, MMMM d, yyyy")
2. 指定英文区域解析
在CsvToBeanBuilder中添加英文Locale配置,确保解析时使用英文规则:
private fun createCSVToBeanUsedVacation(fileReader: BufferedReader?): CsvToBean<UsedVacation> = CsvToBeanBuilder<UsedVacation>(fileReader) .withType(UsedVacation::class.java) .withSkipLines(2) .withIgnoreLeadingWhiteSpace(true) .withLocale(Locale.ENGLISH) // 添加此行指定英文区域 .build()
说明
EEEE:匹配完整的星期名称(如Thursday)MMMM:匹配完整的月份名称(如October)- 指定
Locale.ENGLISH可避免系统区域为非英文环境时,月份、星期名称无法识别的问题
内容的提问来源于stack exchange,提问作者Nemanja Andjelkovic
相关产品推荐
相关产品推荐

