简体   繁体   English

Spring Batch-无法以正确的格式解析日期

[英]Spring Batch - unable to parse date with correct format

In spring batch I'm loading csv file where I'm also parsing dates. 在春季批处理中,我正在加载csv文件,同时还要解析日期。 Everything seems to be working fine except for one single row where I get exception 除了我遇到异常的单行外,其他一切似乎都工作正常

Unparseable date: "2014-03-09 02:07:07", format: [yyyy-MM-dd HH:mm:ss]

I've double checked my input file and there are no special/invisible characters in this failed row. 我已经仔细检查了输入文件,此失败行中没有特殊/不可见的字符。

Caused by: java.lang.IllegalArgumentException: Unparseable date: "2014-03-09 02:07:07", format: [yyyy-MM-dd HH:mm:ss]
    at org.springframework.batch.item.file.transform.DefaultFieldSet.parseDate(DefaultFieldSet.java:778)
    at org.springframework.batch.item.file.transform.DefaultFieldSet.readDate(DefaultFieldSet.java:595)

Thanks for help! 感谢帮助!


EDIT 编辑

When I change hour in date from 02 to something else (eg '2014-03-09 03 :07:07'), it works. 当我在日期更改时间从02到别的东西(如“2014年3月9日03:07:07”),它的工作原理。 When I then change it manually back to 02 it fails again. 然后,当我手动将其更改回02时,它将再次失败。 How can this be possible? 这怎么可能? Changing other elements of date does not help. 更改日期的其他元素无济于事。 Only changing hour. 仅更改小时。

I only experience this on our unix server with America/New_York timezone. 我只在美国/纽约时区的Unix服务器上遇到这种情况。 From my local machine everything is working. 在我的本地计算机上,一切正常。 JDK version on both are identical. 两者的JDK版本相同。

It was caused by combination of TimeZone settings, daylight saving and SimpleDateFormat.lenient property. 这是由TimeZone设置,夏令时和SimpleDateFormat.lenient属性的组合引起的。

Our linux host has America/New_York timezone. 我们的Linux主机具有America/New_York时区。

Date for which I was getting error is 9-MAR-2014 @ 2:07:07 am which is exact date and time when in NYK timezone time shifts 1 hour forward - daylight saving (from 2am to 3am). 我遇到错误的日期是2014年3月9日上午2:07:07,这是确切的日期和时间,在NYK时区,时间向前移动1小时 -夏令时(从凌晨2点到凌晨3点)。

Normally when SimpleDateFormat converts such date it automatically changes it to 3am . 通常,当SimpleDateFormat转换此类日期时,它将自动将其更改为3am Setting lenient property to false (default value for is true ) prevents this and throws exception - HOUR_OF_DAY: 2 -> 3 . lenient属性设置为false (默认值为true )可以防止这种情况,并引发异常HOUR_OF_DAY: 2 -> 3

This exception is consumed in process and at the end we get only IllegalArgumentException with Unparseable date: "2014-03-09 02:07:07", format: [yyyy-MM-dd HH:mm:ss] message. 此异常在处理中使用,最后,我们仅获得IllegalArgumentExceptionUnparseable date: "2014-03-09 02:07:07", format: [yyyy-MM-dd HH:mm:ss]消息。

Here I'm using spring-boot DefaultFieldSet which has implementation where it is specifically setting lenient to false . 在这里,我使用的是spring-boot DefaultFieldSet ,它具有将lenient设置为false

/* ... some other code ... */
private DateFormat dateFormat = new SimpleDateFormat(DEFAULT_DATE_PATTERN);
{
    dateFormat.setLenient(false);
}

/* ... some other code ... */

@Override
public Date readDate(int index, String pattern) {
    SimpleDateFormat sdf = new SimpleDateFormat(pattern);
    sdf.setLenient(false);
    return parseDate(readAndTrim(index), sdf);
}
/* ... some other code ... */

As we are not doing any manipulation with dates in our code, I simply fixed it with changing default timezone to UTC. 由于我们未对代码中的日期进行任何操作,因此我只是通过将默认时区更改为UTC进行了修复。

TimeZone.setDefault(TimeZone.getTimeZone("UTC"));

Other valid approach would be to write custom implementation of FieldSet . 其他有效的方法是编写FieldSet自定义实现。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM