DateTimeFormatter frenchDateFormatter = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.appendPattern("EEE")
.parseCaseSensitive()
.appendPattern(" d MMM uuuu")
.toFormatter(Locale.FRENCH)
.withResolverFields(ChronoField.DAY_OF_MONTH,
ChronoField.MONTH_OF_YEAR, ChronoField.YEAR);
for (String dateString : dates) {
dateString = dateString.replace("jul", "juil.");
String formattedDate = LocalDate.parse(dateString, frenchDateFormatter)
.format(frenchDateFormatter);
System.out.println(formattedDate);
}
从这个打印的问题中给出你的 12 个字符串
sam. 26 janv. 2019
mer. 28 févr. 2018
jeu. 15 mars 2018
mer. 11 avr. 2018
mar. 15 mai 2018
mer. 20 juin 2018
ven. 20 juil. 2018
mer. 22 août 2018
mer. 12 sept. 2018
mer. 24 oct. 2018
ven. 23 nov. 2018
dim. 16 déc. 2018
EEE d MMM uuuu
您的大多数日期字符串已经采用非常标准的格式,可以使用法语语言环境的格式模式识别。例外情况是:
- 有两个问题
mer. 20 jul 2018
:2018 年 7 月 20 日将是星期五 (vendredi, ven.
),而不是星期三 (mercredi, mer.
)。juillet (July)的缩写是juil.
, not jul
(您可能想再次检查该字符串是否真的是您所拥有的字符串)。
- 星期几以法语中的小写字母开头,最后两个字符串 (
Ven.
和Dim.
) 中有一个大写字母。
要解决这些问题:
- 使用格式化程序
withResolverFields()
告诉它使用哪些字段来确定日期;特别是,不要包含星期几,以便格式化程序在解析时容忍错误的星期几。
- 用于
dateString.replace()
修复 7 月的错误月份缩写(我认为这是一个 hack;下面有更好的解决方案)。
- 使用 a
DateTimeFormatterBuilder
及其parseCaseInsensitive
方法构建一个忽略星期几大小写的格式化程序,以便接受Ven.
andDim.
中的大写字母(或者String.toLowercase(Locale.FRENCH)
在解析之前使用)。
jul
编辑:解析而不是juil.
作为月份名称的镀金解决方案是告诉格式化程序我们使用的所有月份名称:
Map<Long, String> monthMap = new HashMap<>();
// first put all the French month abbreviations into the map
for (Month m : Month.values()) {
monthMap.put(Long.valueOf(m.getValue()), m.getDisplayName(TextStyle.SHORT, Locale.FRENCH));
}
// finally overwrite the value for July with the one we get in our input strings
monthMap.put(Long.valueOf(Month.JULY.getValue()), "jul");
DateTimeFormatter frenchDateFormatter = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.appendPattern("EEE")
.parseCaseSensitive()
.appendPattern(" d ")
.appendText(ChronoField.MONTH_OF_YEAR, monthMap)
.appendPattern(" uuuu")
.toFormatter(Locale.FRENCH)
.withResolverFields(ChronoField.DAY_OF_MONTH,
ChronoField.MONTH_OF_YEAR, ChronoField.YEAR);
DateTimeFormatterBuilder.appendText()
有一个重载版本,它接受要打印和解析的文本映射。所以我们构建这样一个映射并将其传递给格式化程序构建器。由于它是从值到文本的映射,每个值只能有一个文本,所以上面只会接受jul
(not juil.
)。但是现在你的字符串mer. 20 jul 2018
可以直接被格式化程序解析,我们不再需要先修复它。另一方面,如果您希望juil.
输出更标准,则需要使用单独的格式化程序进行格式化:DateTimeFormatter.ofPattern("EEE d MMM uuuu", Locale.FRENCH)
.
我正在使用并推荐称为java.time
JSR-310 的现代 Java 日期和时间 API。
但我说我使用的是 Java 1.6
没问题,使用java.time
Java 6 效果很好。
- 在 Java 8 及更高版本以及更新的 Android 设备上,现代 API 是内置的。
- 在 Java 6和 7 中,获取 ThreeTen Backport,即新类的后向端口(JSR 310 的 ThreeTen;请参阅下面的链接)并将其添加到您的项目中。
- 在较旧的 Android 上,使用 ThreeTen Backport 的 Android 版本。它被称为 ThreeTenABP。并确保从
org.threeten.bp
子包中导入日期和时间类。
链接