2

我有以下用于解析日期的代码:

public Boolean isDate(String date, String dateFormat) {
        try {
            DateTimeFormat.forPattern(dateFormat).parseDateTime(date);

        } catch(Exception e) {
            return false;
        }

        return true;

    }

这适用于较新的日期20071001,例如 format yyyyMMdd。但是对于早于 1970 年的日期,例如19600101具有相同格式的yyyyMMdd,该方法返回 false。

任何关于我如何解决这个问题的想法都将不胜感激。

更新:

我得到的例外是:

Cannot parse "19400101": Illegal instant due to time zone offset transition (Africa/Nairobi)

这就是我调用该方法的方式:

if(validationUtils.isDate(propVal, dateFormat) == false) {
                    String msg = "Not a valid DATE";
                    Quartet<String, String, String, String> t = new Quartet<String, String, String, String>(recNo, field, propVal, msg);
                    errors.add(t);
                }

包含该isDate方法的类是一个我使用的 bean @Autowired IValidationUtils validationUtils。这不是我正在做的唯一验证。其他验证工作成功了,这让我得出结论,问题出在 Joda Time 上。

更新(解决方案):

按照@Ettiene 的建议(在下面的答案中),我找到了解决问题的方法。修改后的工作代码是:

public Boolean isDate(String date, String dateFormat) {
        try {
            DateTimeFormatter fmt = DateTimeFormat.forPattern(dateFormat);
            DateTime dt = fmt.withZone(DateTimeZone.UTC).parseDateTime(date);

        } catch(Exception e) {
            return false;
        }

        return true;

    }
4

2 回答 2

2

这个问题似乎与从冬季时间到夏季时间的过渡有关。问题是由于过渡,某些日期在某些时区无效。

例如,在法国/巴黎时区,2013-03-31T02:30 无效,因为从冬季时间切换到夏季时间发生在当天凌晨 2:00,因此 2013-03-31T01:59 之后的分钟是 2013-03 -31T03:00。

我猜在你的时区,okello,在 1970 年之前,过渡发生在 1 月 1 日午夜。因此,1960-01-01T00:00 无效(但 1959-12-31T00:00 和 1960-01-02T00:00 有效)。

请记住,如果未指定一天中的时间,则假定为午夜。

于 2013-05-15T12:54:37.610 回答
1

不要使用parseDateTime(),使用parseLocalDate()(自 2.0 起可用)

这是概念上正确的方法(您解析的不是日期时间而是日期)并且很健壮(您无需担心时区、DST 转换以及与您的问题完全不同的所有内容)。

此外,您应该只 catch IllegalArgumentException,其他异常应该被重新抛出或以不同的方式捕获。

于 2013-05-16T17:24:16.500 回答