Utilisation de la nouvelle Java 8 DateTimeFormatter pour effectuer l'analyse stricte de la date

j'ai un problème simple : je veux analyser les cordes de Java dans le format "yyyyMMdd" strictement, de sorte que "19800229" est une date valide, mais "19820229" ne l'est pas. Supposons qu'il s'agisse de dates AD du calendrier grégorien normal.

je suis en train d'utiliser la nouvelle java.time paquet de JDK 8 pour résoudre ce problème, mais il s'avère plus compliqué que prévu. Mon code est:

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

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

cependant, l'analyse d'une date valide telle que "19800228" produit ce qui pour moi est un incompréhensible erreur:

java.temps.format.DateTimeParseException: le texte "19820228" n'a pas pu être analysé: impossible d'obtenir LocalDate à partir de TemporalAccessor: {MonthOfYear=2, DayOfMonth=28, YearOfEra=1982},ISO de type java.temps.format.Analysée

comment utiliser java.time.format.DateTimeFormatter pour résoudre mon cas simple d'utilisation?

11
demandé sur 0xbe5077ed 2014-10-16 03:07:15

3 réponses

j'édite pour limiter quel type de chaîne sera considéré valide en utilisant un formatteur personnalisé créé avec un 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 est invalide et lancerait ce qui suit:

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

une date de 19800228-5000 fonctionnerait avec BASIC_ISO_DATE car elle permet l'offset optionnel que vous ne voulez pas autorisé. Mon formatteur CUSTOM_BASIC_ISO_DATE ne permettra pas cela et lancera ce qui suit:

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

notez, si vous êtes sûr de la longueur de la chaîne, yyyyMMdd alors vous pouvez toujours travailler avec la sous-couche des 8 premières charrettes pour nier la nécessité du résolveur. Cependant, c'est deux choses différentes. Le résolveur marquera les formats de date Invalides à l'entrée et la sous-chaîne rayera bien sûr les caractères supplémentaires.

2
répondu TechTrip 2014-10-16 07:07:11

Java 8 utilise uuuu pour l'année, pas yyyy. En Java 8,