問題描述
我需要解析以下形式的(德語)日期:
I need to parse (German) dates that come in the following form:
10. Jan. 18:14
8. Feb. 19:02
1. M?r. 19:40
4. Apr. 18:55
2. Mai 21:55
5. Juni 08:25
5. Juli 20:09
1. Aug. 13:42
[...]
如您所見,如果月份的字符數(shù)超過 4 個(gè),則月份名稱會(huì)被刪減.更奇怪的是,不要問我為什么,盡管全名是 M?rz
,但 3 月份縮短為 M?r.
.如何用 java.time
解析這個(gè)?(日期是根據(jù)創(chuàng)建日期列表的 android 設(shè)備的本地化格式化的.但是,我不會(huì)在 Android 上解析它)
As you can see, the month names are cut if the month has more than 4 characters. Even weirder, don't aks me why, the month of March is shortened to M?r.
although the whole name is M?rz
. How can I parse this with java.time
?
(The dates are formatted based on the localization of the android device that creates the list of dates. However, I'm not parsing it on Android)
我的方法是像這樣創(chuàng)建一個(gè) DateTimeFormatter
:
My approach was to create a DateTimeFormatter
like this:
DateTimeFormatter.ofPattern("d. MMMM HH:mm").withLocale(Locale.GERMAN);
// or
DateTimeFormatter.ofPattern("d. MMMMM HH:mm").withLocale(Locale.GERMAN);
但是 MMMM
和 MMMMM
模式都不適合縮短的日期.當(dāng)然,我可以使用以下模式 d.嗯.HH:mm
來匹配縮短的月份,但是我無法匹配 3 和 4 個(gè)字符的月份.我知道我可以有兩個(gè)格式化程序(MMM. 和 MMMMM
),但我寧愿有一個(gè)解決方案,我只有一個(gè)格式化程序,可能還有一個(gè)自定義語言環(huán)境或類似的東西.
But neither the MMMM
nor the MMMMM
pattern fit the dates that are shortened. I can, of course, have the following pattern d. MMM. HH:mm
to match the shortened months, but then I can't match the 3 and 4 characters months. I am aware that I can have two formatters (MMM. and MMMMM
) but I would rather have a solution where I have only one formatter and possibly a custom locale or something like this.
推薦答案
問題的答案是DateTimeFormatterBuilder
類和 appendText(TemporalField, Map)
方法.它允許任何文本在格式化或解析時(shí)與一個(gè)值關(guān)聯(lián),從而有效而優(yōu)雅地解決問題:
The answer to the problem is the DateTimeFormatterBuilder
class and the appendText(TemporalField, Map)
method. It allows any text to be associated with a value when formatting or parsing, which solves the problem effectively and elegantly:
Map<Long, String> monthNameMap = new HashMap<>();
monthNameMap.put(1L, "Jan.");
monthNameMap.put(2L, "Feb.");
monthNameMap.put(3L, "Mar.");
DateTimeFormatter fmt = new DateTimeFormatterBuilder()
.appendPattern("d. ")
.appendText(ChronoField.MONTH_OF_YEAR, monthNameMap)
.appendPattern(" HH:mm")
.parseDefaulting(ChronoField.YEAR, 2016)
.toFormatter();
System.out.println(LocalDateTime.parse("10. Jan. 18:14", fmt));
System.out.println(LocalDateTime.parse("8. Feb. 19:02", fmt));
一些注意事項(xiàng):
monthNameMap
必須填寫所有 12 個(gè)月- 格式化程序通常應(yīng)分配給靜態(tài)最終常量,而不是一直創(chuàng)建
- 已添加
parseDefaulting(YEAR, 2016)
,以便可以直接使用LocalDateTime.parse(String, DateTimeFormatter)
.沒有它,就沒有年份,因此只能解析TemporalAccessor
(年份必須是閏年,以防解析 2 月 29 日)
- The
monthNameMap
must be populated with all 12 months - The formatter should normally be assigned to a static final constant, rather than being created all the time
- The
parseDefaulting(YEAR, 2016)
has been added so thatLocalDateTime.parse(String, DateTimeFormatter)
can be used directly. Without it, there would be no year, and thus nothing more than aTemporalAccessor
could be parsed (the year must be a leap year, in case 29th Feb is being parsed)
這篇關(guān)于如何使用 DateTimeFormatter 解析非標(biāo)準(zhǔn)月份名稱的文章就介紹到這了,希望我們推薦的答案對(duì)大家有所幫助,也希望大家多多支持html5模板網(wǎng)!