使用新的Java 8 DateTimeFormatter进行严格的日期解析 [英] Using new Java 8 DateTimeFormatter to do strict date parsing

查看:5971
本文介绍了使用新的Java 8 DateTimeFormatter进行严格的日期解析的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的问题:我想严格地解析格式为yyyyMMdd的Java字符串,以便19800229是有效的日期,但19820229不是。假设这些是正常公历的日期。



我正在尝试使用新的 java.time package从JDK 8来解决这个问题,但是比起希望复杂得多。我现在的代码是:

  private static final DateTimeFormatter FORMAT = DateTimeFormatter 
.ofPattern(yyyyMMdd)。withChronology IsoChronology.INSTANCE)
.withResolverStyle(STRICT);

public static LocalDate parse(String yyyyMMdd){
return LocalDate.parse(yyyyMMdd,FORMAT);
}

但是,解析有效的日期如19800228会产生什么一个不可理解的错误:


java.time.format.DateTimeParseException:无法解析文本'19820228':无法从TemporalAccessor获取LocalDate: {MonthOfYear = 2,DayOfMonth = 28,YearOfEra = 1982},类型为java.time.format.Parsed的ISO


使用 java.time.format.DateTimeFormatter 来解决我的简单用例?

解决方案

我正在进行编辑,以限制使用DateTimeFormatterBuilder创建的自定义格式化程序将被视为有效的字符串。

  public class DateFormmaterTest {

static DateTimeFormatter CUSTOM_BASIC_ISO_DATE = new DateTimeFormatterBuilder()
.parseCaseInsensitive()。appendValue(YEAR,4)
.appendValue(MONTH_OF_YEAR,2).appendValue DAY_OF_MONTH, 2)
.optionalStart()。toFormatter()
.withResolverStyle(ResolverStyle.STRICT)
.withChronology(IsoChronology.INSTANCE);

public static void main(String [] args){

LocalDate date1 = LocalDate.parse(19800228-5000,
CUSTOM_BASIC_ISO_DATE);

System.out.println(date1);

}
}

2/29/1982无效并将抛出以下内容:

 导致:java.time.DateTimeException:'1982年'不是闰年
在java.time.LocalDate.create(LocalDate.java:429)

19800228-5000的日期将使用BASIC_ISO_DATE,因为它允许您不希望允许的可选偏移。我的CUSTOM_BASIC_ISO_DATE格式化程序不会允许这样做,并抛出以下内容:

 线程main中的异常java.time.format.DateTimeParseException:文本'19800228-5000'无法解析,在索引8处找到未解析的文本。

注意,如果你确定字符串的长度,yyyyMMdd,那么你总是可以使用前8个字符的子串来否定解析器的需要。但这是两个不同的东西。解析器将在输入时标记无效的日期格式,而子串当然只会删除额外的字符。


I have a simple problem : I want to parse Java strings in format "yyyyMMdd" strictly, so that "19800229" is a valid date, but "19820229" is not. Assume these are AD dates from the normal Gregorian calendar.

I am trying to use the new java.time package from JDK 8 to solve this problem, but it is proving more complicated than hoped. My current code is:

private static final DateTimeFormatter FORMAT = DateTimeFormatter
        .ofPattern("yyyyMMdd").withChronology(IsoChronology.INSTANCE)
        .withResolverStyle(STRICT);

public static LocalDate parse(String yyyyMMdd) {
    return LocalDate.parse(yyyyMMdd, FORMAT);
}

However, parsing a valid date such as "19800228" produces what to me is an incomprehensible error:

java.time.format.DateTimeParseException: Text '19820228' could not be parsed: Unable to obtain LocalDate from TemporalAccessor: {MonthOfYear=2, DayOfMonth=28, YearOfEra=1982},ISO of type java.time.format.Parsed

How do I use java.time.format.DateTimeFormatter to solve my simple use case?

解决方案

I'm editing to limit what kind of string will be considered valid by using a custom formatter created with a DateTimeFormatterBuilder.

public class DateFormmaterTest {

    static DateTimeFormatter CUSTOM_BASIC_ISO_DATE = new DateTimeFormatterBuilder()
            .parseCaseInsensitive().appendValue(YEAR, 4)
            .appendValue(MONTH_OF_YEAR, 2).appendValue(DAY_OF_MONTH, 2)
            .optionalStart().toFormatter()
            .withResolverStyle(ResolverStyle.STRICT)
            .withChronology(IsoChronology.INSTANCE);

    public static void main(String[] args) {

        LocalDate date1 = LocalDate.parse("19800228-5000",
                CUSTOM_BASIC_ISO_DATE);

        System.out.println(date1);

    }
}

2/29/1982 is invalid and would throw the following:

Caused by: java.time.DateTimeException: Invalid date 'February 29' as '1982' is not a leap year
    at java.time.LocalDate.create(LocalDate.java:429)

A date of 19800228-5000 would work with BASIC_ISO_DATE because it allows the optional offset which you don't want allowed. My CUSTOM_BASIC_ISO_DATE formatter will not allow that and throw the following:

Exception in thread "main" java.time.format.DateTimeParseException: Text '19800228-5000' could not be parsed, unparsed text found at index 8. 

Note, if you are sure of the string length, yyyyMMdd then you could always work with the substring of first 8 chars to negate the need for the resolver. However that is two different things. The resolver will flag invalid date formats on input and the substring would of course just strip the extra chars out.

这篇关于使用新的Java 8 DateTimeFormatter进行严格的日期解析的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆