我们的客户今天发现了一个有趣的错误。请考虑以下方法:
iso
(如果您不知道,这些确实是英语和德语的正确日期。我甚至会说它们是相同的日期[2017年4月1日]。花点时间考虑一下您认为这个应用程序的内容应该回来。)
它返回的内容如下:
final DateTimeFormatter englishFormatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT).withLocale(Locale.ENGLISH);
System.out.println(LocalDate.parse("04/01/17", englishFormatter));
System.out.println(LocalDate.parse("4/1/17", englishFormatter));
final DateTimeFormatter germanFormatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT).withLocale(Locale.GERMAN);
System.out.println(LocalDate.parse("01.04.17", germanFormatter));
System.out.println(LocalDate.parse("1.4.17", germanFormatter));
英文日期格式可以使用和不使用前导零。德语格式仅适用于前导零。
我似乎无法找到一个属性来更改此行为以正常工作。
如何让Exception in thread "main" java.time.format.DateTimeParseException: Text '1.4.17' could not be parsed at index 0
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)
at Main.main(Main.java:20)
在不带前导零的情况下理解德语日期?
注意:我们的应用程序支持多种语言环境,因此使用特定的DateTimeFormatter
(如DateTimeFormatter
)是完全不可能的,特别是因为我们要解析< em>默认日期格式。
答案 0 :(得分:2)
我尝试了相反的方法:使用本地化格式化程序格式化日期。
LocalDate testDate = LocalDate.of(2017, Month.APRIL, 1);
final DateTimeFormatter englishFormatter
= DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT)
.withLocale(Locale.ENGLISH);
System.out.println("English: " + testDate.format(englishFormatter));
final DateTimeFormatter germanFormatter
= DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT)
.withLocale(Locale.GERMAN);
System.out.println("German: " + testDate.format(germanFormatter));
我得到了
English: 4/1/17 German: 01.04.17
所以很明显,Java认为标准的德语日期格式使用前导零。如果您确定这是错误的,您可以考虑向Oracle提交错误。
为了规避你不喜欢的行为,使用多个语言环境我恐怕你需要某种黑客攻击。我能想到的最好的黑客是以下内容。它不漂亮。它有效。
private static final Map<Locale, DateTimeFormatter> STEFFI_S_LOCALIZED_FORMATTERS
= createSteffiSFormatters();
private static Map<Locale, DateTimeFormatter> createSteffiSFormatters() {
Map<Locale, DateTimeFormatter> formatters = new HashMap<>(2);
formatters.put(Locale.GERMAN, DateTimeFormatter.ofPattern("d.M.uu"));
return formatters;
}
public static DateTimeFormatter getLocalizedFormatter(Locale formattingLocale) {
DateTimeFormatter localizedFormatter
= STEFFI_S_LOCALIZED_FORMATTERS.get(formattingLocale);
if (localizedFormatter == null) {
localizedFormatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT)
.withLocale(formattingLocale);
}
return localizedFormatter;
}
现在你可以做到:
final DateTimeFormatter englishFormatter = getLocalizedFormatter(Locale.ENGLISH);
System.out.println(LocalDate.parse("04/01/17", englishFormatter));
System.out.println(LocalDate.parse("4/1/17", englishFormatter));
final DateTimeFormatter germanFormatter = getLocalizedFormatter(Locale.GERMAN);
System.out.println(LocalDate.parse("01.04.17", germanFormatter));
System.out.println(LocalDate.parse("1.4.17", germanFormatter));
打印:
2017-04-01
2017-04-01
2017-04-01
2017-04-01
答案 1 :(得分:2)
一种解决方案是捕获DateTimeParseException,然后使用修改/缩减日期模式再次尝试。
import java.text.Format;
import java.time.LocalDate;
import java.time.chrono.IsoChronology;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.DateTimeParseException;
import java.time.format.FormatStyle;
import java.util.ListResourceBundle;
import java.util.Locale;
public class Demo {
public static void main(String[] args) {
Locale[] locales = {Locale.ENGLISH, Locale.GERMAN};
for (Locale locale : locales)
{
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT).withLocale(locale);
String [] englishDates = {"01/04/17","1/4/17"};
String [] germanDates = {"01.04.17","1.4.17"};
String datePattern = DateTimeFormatterBuilder.getLocalizedDateTimePattern(FormatStyle.SHORT,null, IsoChronology.INSTANCE, locale);
System.out.println("Locale " + locale.getDisplayName() + ": Default Date Pattern (short): " + datePattern);
String[] dates = null;
if (locale == Locale.ENGLISH)
dates = englishDates;
else
dates = germanDates;
for (String date : dates) {
try {
System.out.printf(" " + date + " -> ");
System.out.println(LocalDate.parse(date, formatter));
}
catch (DateTimeParseException e)
{
System.out.println("Error!");
// Try alternate pattern
datePattern = datePattern.replace("dd", "d").replace("MM", "M");
System.out.println(" Modified Date Pattern (short): " + datePattern);
// Allow single digits in day and month
DateTimeFormatter modifiedFormatter = DateTimeFormatter.ofPattern(datePattern);
System.out.println(" " + date + " -> " + LocalDate.parse(date, modifiedFormatter)); // OK
}
}
}
}
}
这给出了:
Locale English: Default Date Pattern (short): M/d/yy
01/04/17 -> 2017-01-04
1/4/17 -> 2017-01-04
Locale German: Default Date Pattern (short): dd.MM.yy
01.04.17 -> 2017-04-01
1.4.17 -> Error!
Modified Date Pattern (short): d.M.yy
1.4.17 -> 2017-04-01