[英]JodaTime convert from Java.util.Date to DateTime (or LocalDate)
[英]Cannot convert from Spanish date string to LocalDate in Java
您好,我是來解決 Locale 格式化程序語言的 DateTimeFormatter 問題的,讓我向您介紹一下:
觀察到堆棧跟蹤錯誤:
Exception in thread "main" java.time.format.DateTimeParseException: Text '28-dic-2017' could not be parsed at index 3
at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2051)
at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1953)
at java.base/java.time.LocalDate.parse(LocalDate.java:429)
at com.examen.Presentation.Principal.parseDate(Principal.java:28)
at com.examen.Presentation.Principal.main(Principal.java:19)
最小的、可重現的代碼示例:
public static LocalDate parseDate(String fecha) {
Locale loc = new Locale("es", "ES");
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MMM-yyyy", loc);
LocalDate date = LocalDate.parse(fecha, formatter);
return date;
}
我從語言環境嘗試不同的事情和方法時遇到了同樣的錯誤,而 DateTimeFormatter 甚至不知道我在做什么,但我認為這顯然不應該起作用。
在另一個答案中,geocodezip 已經解釋了您的嘗試失敗的原因。 這里有兩個解決方案的建議,我發現它們比那個答案中的那個更優雅。
Java 可以從多達四個來源獲取其區域設置數據,包括不同語言的月份縮寫。 由於 Java 9 默認情況下,它更喜歡從 CLDR、Unicode 公共區域設置數據存儲庫中獲取它們。 在 CLDR 西班牙語月份縮寫帶有一個點(或全點),如另一個答案中所述,如dic.
為diciembre 。 另一個來源是自早期版本以來內置於 Java 的語言環境數據(在 Java 8 之前一直是默認設置)。 這里西班牙月份的縮寫沒有點(你的數據可能是由在 Java 8 或更早版本上運行的程序生成的,我不知道)。 這些語言環境數據被稱為COMPAT
,以與早期的 Java 版本兼容。 啟動程序時,您可以在命令行中指定 Java 應該更喜歡 COMPAT 而不是 CLDR,例如:
java -Djava.locale.providers=COMPAT,CLDR YourJavaMainClass
這將導致您現有的代碼接受dic
和其他不帶點的月份縮寫。
這是 JVM 的全局設置,因此它還會導致您的程序中的任何位置以及在同一 JVM 中運行的其他程序中的任何區域設置敏感操作都使用來自 ZD52387880E1522817A72D7 的舊區域設置數據。
由於您知道您的格式始終為28-dic-2017
,因此您還可以通過明確指定輸入數據中使用的月份縮寫來使自己完全獨立於任何語言環境數據。
private static Map<Long, String> getMonthAbbreviations() {
return Map.ofEntries(
Map.entry(1L, "ene"),
Map.entry(2L, "feb"),
Map.entry(3L, "mar"),
Map.entry(4L, "abr"),
Map.entry(5L, "may"),
Map.entry(6L, "jun"),
Map.entry(7L, "jul"),
Map.entry(8L, "ago"),
Map.entry(9L, "sep"),
Map.entry(10L, "oct"),
Map.entry(11L, "nov"),
Map.entry(12L, "dic"));
}
private static final DateTimeFormatter inputDateFormatter = new DateTimeFormatterBuilder()
.appendPattern("dd-")
.appendText(ChronoField.MONTH_OF_YEAR, getMonthAbbreviations())
.appendPattern("-uuuu")
.toFormatter();
此格式化程序獨立於語言環境並解析您的日期字符串:
String fecha = "28-dic-2017";
LocalDate date = LocalDate.parse(fecha, inputDateFormatter);
System.out.println(date);
Output 是:
2017-12-28
提示:當解析不起作用時,您可以先嘗試格式化以了解要解析的字符串應該是什么樣子,並與您嘗試解析的字符串進行比較。 例如:
Locale loc = new Locale("es", "ES");
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MMM-yyyy", loc);
System.out.println("Want to parse: 28-dic-2017");
System.out.println("Formatted: "
+ LocalDate.of(2017, Month.DECEMBER, 28).format(formatter));
System.out.println("Want to parse: 29-sep-2017");
System.out.println("Formatted: "
+ LocalDate.of(2017, Month.SEPTEMBER, 29).format(formatter));
Want to parse: 28-dic-2017 Formatted: 28-dic.-2017 Want to parse: 29-sep-2017 Formatted: 29-sept.-2017
現在我們至少可以一開始就看到哪里出了問題。
LocaleServiceProvider
在 Java 中列出了可能的語言環境數據來源DateTimeFormatterBuilder.appendText(TemporalField, Map)
對於西班牙語, DateTimeFormatter
期望縮寫的月份以句點結束。 像這樣: 28-dic.-2017
如果您的所有日期都采用該格式,您可以解析輸入字符串以添加句點,然后將其發送到DateTimeFormatter
:
public static LocalDate parseDate(String fecha) {
int firstDash = fecha.indexOf('-')+1;
int secondDash = fecha.indexOf('-', fecha.indexOf('-')+1);
String month = fecha.substring(firstDash, secondDash);
String dateStr = fecha.substring(0,firstDash)+month+"."+fecha.substring(secondDash);
Locale loc = new Locale("es", "ES");
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MMM-yyyy", loc);
LocalDate date = LocalDate.parse(dateStr, formatter);
return date;
}
如果格式有時有句點,如果它不存在,則需要添加它:
public static LocalDate parseDate(String fecha) {
String dateStr;
if (fecha.indexOf(".")!=-1) {
dateStr = fecha;
} else {
int firstDash = fecha.indexOf('-')+1;
int secondDash = fecha.indexOf('-', fecha.indexOf('-')+1);
String month = fecha.substring(firstDash, secondDash);
dateStr = fecha.substring(0,firstDash)+month+"."+fecha.substring(secondDash);
}
System.out.println(dateStr);
Locale loc = new Locale("es", "ES");
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MMM-yyyy", loc);
LocalDate date = LocalDate.parse(dateStr, formatter);
return date;
}
output:
2017-12-28
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.