使用OpenCsv解析Instant



我正试图通过以下方式使用OpenCsv从CSV解析Instant:

@CsvDate("yyyy-MM-dd hh:mm:ss")
@CsvBindByName(column = "date")
private Instant date;

我知道OpenCsv应该支持java.time

但当尝试使用它时,我会遇到以下异常:

分析CSV行时出错:8。

。。。

由以下原因引起:java.time.format.DateTimeParseException:无法解析文本"2022-04-21 00:00:00":无法从TemporalAccessor:{HourOfAmPm=0,MicroOfSecond=0,NanoOfSecond=0、MilliOfSecond=0,MinuteOfHour=0,SecondOfMinute=0},ISO解析为java.time.fformat.parsed 类型的2022-04-21

。。。

由以下原因引起:java.time.DateTimeException:无法从TemporalAccessor:{HourOfAmPm=0,MicroOfSecond=0,NanoOfSecond=0、MilliOfSecond=0,MinuteOfHour=0,SecondOfMinute=0},ISO解析为java.time.format.Parsed 类型的2022-04-21

。。。

由java.time.temporal.UnsupportedTemporalTypeException引起:不支持的字段:InstantSeconds

我的调查表明,根本原因是缺少时区,但我的问题是如何仅使用注释指定时区?

请参阅DateTimeFormatter。应为HH,持续24小时(0-23(,或hh,持续12小时(1-12(。该错误是由小时"引起的;00";。幸运的是,否则你将只有前半天的时间。

参见h、k、h和k。

Instant不使用秒之类的单位,在内部更为长。使用LocalDateTime作为您的格式。

我的调查得出的结论是,根本原因是缺少时区,但我的问题是如何仅使用注释指定时区?

我还没有找到更改OpenCSV使用的DateTimeFormatter时区的方法。理论上,您可以使用@CsvCustomBindByName,并提供一个自定义转换器,在该转换器中,您可以将自己的DateTimeFormatter与所需时区一起使用。

但是,如果您还控制CSV的生成方式,您可以简单地使用以下日期时间模式使其与Instant:一起工作

@CsvBindByName(column = "date")
@CsvDate(
value = "yyyy-MM-dd'T'HH:mm:ssX",
writeFormat = "yyyy-MM-dd'T'HH:mm:ss'Z'",
writeFormatEqualsReadFormat = false)
private Instant date;

value是从CSV文件中读取bean时使用的模式。X是一个模式字母,它将对应于区域偏移,即当读取"Z"字符时,它将假定时间为UTC+00:00。参见文档。

当将bean写入CSV文件时,将使用writeFormat模式,并且需要有所不同,您需要在末尾手动打印"Z"字符,从而获得转义的'Z'。原因是内部OpenCSV在编写Instant:时会执行以下操作

LocalDateTime ldt = LocalDateTime.ofInstant((Instant) value, ZoneId.of("UTC"));
return writeDtf.format(ldt);

LocalDateTime没有时区,因此不能使用X。可以说,他们可以做以下事情:

return writeDtf.withZone(ZoneOffset.UTC).format(value);

这将允许我们使用X。为了保持一致,他们也可以在将日期解析为Instant时执行同样的操作。

相关内容

  • 没有找到相关文章

最新更新