使用 DateTimeFormatter 解析具有模式 'dd MMMMM uuuu' 的日期
Parsing a date with pattern 'dd MMMMM uuuu' using DateTimeFormatter
为什么这段代码给我一个异常?
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);
异常:
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)
如果我尝试使用 'MMMM' 而不是 'MMMMM',它会按预期工作。
String myFormat = "dd MMMM uuuu";
正如 DateTimeFormatter
的 javadoc 解释的那样,我引用:正好 4 个模式字母将使用完整形式。恰好 5 个模式字母将使用窄格式。
我也不知道为什么;窄形式实际上非常非常短,大概几个月以来它都是第一个字母,这是非常无用的,例如 june 和 july 都以 J 开头(即使是德语)。弄清楚这种事情的最简单方法是反过来:取一个已知日期并使用 .format
而不是 .parse
来查看它的样子。
你要的是字母M的4倍,也就是月份的完整名称。
正如一些评论所说,它的确切功能将取决于您的系统区域设置,这使得测试和建议比需要的困难得多。通常,您应该始终明确选择语言环境。可以调用withLocale
方法强制执行。
下面是一些示例代码:
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);
}
}
为什么这段代码给我一个异常?
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);
异常:
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)
如果我尝试使用 'MMMM' 而不是 'MMMMM',它会按预期工作。
String myFormat = "dd MMMM uuuu";
正如 DateTimeFormatter
的 javadoc 解释的那样,我引用:正好 4 个模式字母将使用完整形式。恰好 5 个模式字母将使用窄格式。
我也不知道为什么;窄形式实际上非常非常短,大概几个月以来它都是第一个字母,这是非常无用的,例如 june 和 july 都以 J 开头(即使是德语)。弄清楚这种事情的最简单方法是反过来:取一个已知日期并使用 .format
而不是 .parse
来查看它的样子。
你要的是字母M的4倍,也就是月份的完整名称。
正如一些评论所说,它的确切功能将取决于您的系统区域设置,这使得测试和建议比需要的困难得多。通常,您应该始终明确选择语言环境。可以调用withLocale
方法强制执行。
下面是一些示例代码:
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);
}
}