简体   繁体   English

使用DateTimeFormatter解析模式为“ dd MMMMM uuuu”的日期

[英]Parsing a date with pattern 'dd MMMMM uuuu' using DateTimeFormatter

Why this code give me an Exception? 为什么这段代码给我一个异常?

String myFormat = "dd MMMMM uuuu";
String dateToFormat = "26 Mai 2010";
DateTimeFormatter myFormatter = new DateTimeFormatterBuilder().appendPattern(myFormat)
            .toFormatter().withResolverStyle(ResolverStyle.STRICT);
LocalDate myDate=LocalDate.parse(dateToFormat,myFormatter);

Exception: 例外:

java.time.format.DateTimeParseException: Text '26 Mai 2010' could not be parsed at index 4
    at java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1949)
    at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1851)
    at java.time.LocalDate.parse(LocalDate.java:400)

If I try with 'MMMM' instead of 'MMMMM' than it works as expected. 如果我尝试使用“ MMMM”而不是“ MMMMM”,它将按预期工作。

String myFormat = "dd MMMM uuuu";

As the javadoc of DateTimeFormatter explains, and I quote: Exactly 4 pattern letters will use the full form. 正如DateTimeFormatter的javadoc解释的那样,我引用: 恰好4个模式字母将使用完整格式。 Exactly 5 pattern letters will use the narrow form. 恰好5个图案字母将使用窄幅形式。

I don't know why either; 我也不知道为什么。 narrow forms are actually very very short, presumably for months it'd be the first letter, which is extremely useless, as for example both june and july start with a J (even in german). 窄形式实际上非常短,大​​概几个月以来,这是第一个字母,这是非常没有用的,例如,六月和七月都以J开头(即使是德语)。 The easiest way to figure this kind of thing out is to go in reverse: Take a known date and use .format instead of .parse to see what it looks like. 解决这类问题的最简单方法是逆向操作:获取一个已知日期并使用.format而不是.parse来查看其外观。

What you want is 4x the letter M, which is the complete name of the month. 您想要的是字母M的4倍,字母M是月份的全名。

As a few comments have said, how it functions exactly will depend on your system locale which makes testing and advice much harder than it needs to be. 正如一些评论所言,它的确切功能将取决于您的系统区域设置,这会使测试和建议变得更加困难。 Generally, you should always explicitly choose a locale. 通常,您应该始终明确选择语言环境。 You can call the withLocale method to force it. 您可以调用withLocale方法来强制执行此操作。

Here's some sample code to play with: 以下是一些示例代码:

import java.time.*; import java.time.format.*; import java.util.*;

public class Test {
    public static void main(String[] args) {
        String myFormatNarrow = "dd MMMMM uuuu";
        String myFormatFull = "dd MMMM uuuu";
        String dateToFormat = "26 Juni 2010";
        String dateToFormat2 = "26 J 2010";
        String dateToFormat3 = "26 Jun 2010";
        DateTimeFormatter myFormatter;
        LocalDate myDate;
        myFormatter = new DateTimeFormatterBuilder().appendPattern(myFormatFull)
                    .toFormatter().withResolverStyle(ResolverStyle.STRICT).withLocale(Locale.GERMAN);
        System.out.println("FULL: " + myFormatter.format(LocalDate.of(2010, 6, 26)));
        myDate = LocalDate.parse(dateToFormat, myFormatter);
        System.out.println("PARSED: " + myDate);
        myFormatter = new DateTimeFormatterBuilder().appendPattern(myFormatNarrow)
                    .toFormatter().withResolverStyle(ResolverStyle.STRICT).withLocale(Locale.GERMAN);
        System.out.println("NARROW: " + myFormatter.format(LocalDate.of(2010, 6, 26)));
        myDate = LocalDate.parse(dateToFormat2, myFormatter);
        // It parses a single J as 'july'. Clearly showing why narrow-form is useless here.
        System.out.println("PARSED: " + myDate);
        // note that even ResolverStyle.LENIENT can't do it either; this will fail:
        myFormatter = myFormatter.withResolverStyle(ResolverStyle.LENIENT);
    //   myDate = LocalDate.parse(dateToFormat3, myFormatter);
    // System.out.println("PARSED: " + myDate);
    }
}

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

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