我需要使用 DateTimeFormatter 將字串決議為 LocalDate。
有兩種不同的情況,模式字串 dMMyy 或 ddMMyy (20320, 020320, 120320) 和模式字串 ddMMyyyy 或 dMMyyyy (2032020, 02032020, 12032020)。
對于第一種情況,我可以只使用 DateTimeFormatter.ofPattern("dMMyy") 它適用于 5 或?? 6 位長日期。
@Test
public void dateConversionyy() {
DateTimeFormatter worksShortd = DateTimeFormatter.ofPattern("dMMyy");
DateTimeFormatter worksShortdd = DateTimeFormatter.ofPattern("ddMMyy");
String longString = "120320";
String leadingZeroString = "020320";
String shortString = "20320";
LocalDate res = LocalDate.parse(longString, worksShortd);
assertNotNull(res);
LocalDate res2 = LocalDate.parse(longString, worksShortdd);
assertNotNull(res2);
assertEquals(res, res2);
LocalDate res3 = LocalDate.parse(shortString, worksShortd);
assertNotNull(res3);
LocalDate res4 = LocalDate.parse(leadingZeroString, worksShortd);
assertNotNull(res4);
assertEquals(res3, res4);
LocalDate res5 = LocalDate.parse(leadingZeroString, worksShortdd);
assertNotNull(res);
assertEquals(res3, res5);
}
對于第二種情況,我認為我可以使用模式“dMMyyyy”,但它只是不決議任何輸入字串。
@Test
public void dateConversionyyyy() {
LocalDate res;
DateTimeFormatter failsLong = DateTimeFormatter.ofPattern("dMMyyyy");
DateTimeFormatter worksLong = DateTimeFormatter.ofPattern("ddMMyyyy");
String longString = "13082020";
String shortString = "3082020";
boolean notParsed1 = false;
try {
LocalDate.parse(longString, failsLong);
} catch (DateTimeParseException e) {
notParsed1 = true;
}
assertTrue(notParsed1);
res = LocalDate.parse(longString, worksLong);
assertNotNull(res);
boolean notParsed2 = false;
try {
LocalDate.parse(shortString, failsLong);
} catch (DateTimeParseException e) {
notParsed2 = true;
}
assertTrue(notParsed2);
}
編輯:我的問題:有沒有辦法實體化 DateTimeFormatter使用 DateTimeFormatter.ofPattern以決議 7-8 位變體的方式?
編輯問題以便@user16320675 答案匹配,因為它解決了我的問題。
uj5u.com熱心網友回復:
DateTimeFormatterBuilder.appendValue(TemporalField, int)
我正在使用并稍微修改 user16320675 在評論中提到的想法:
嘗試使用 a
DateTimeFormatterBuilder和 useappendValue(ChronoField.DAY_OF_MONTH, 1, 2, SignStyle.NEVER),其他欄位使用固定大小。
DateTimeFormatter worksLong = new DateTimeFormatterBuilder()
.appendPattern("dMM")
.appendValue(ChronoField.YEAR, 4)
.toFormatter(Locale.ROOT);
System.out.println(LocalDate.parse("2032020", worksLong));
System.out.println(LocalDate.parse("02032020", worksLong));
System.out.println(LocalDate.parse("12032020", worksLong));
輸出:
2020-03-02 2020-03-02 2020-03-12
如果您希望在構建格式化程式時更加一致:
DateTimeFormatter worksLong = new DateTimeFormatterBuilder()
.appendValue(ChronoField.DAY_OF_MONTH)
.appendValue(ChronoField.MONTH_OF_YEAR, 2)
.appendValue(ChronoField.YEAR, 4)
.toFormatter(Locale.ROOT);
結果是一樣的。
為什么你的模式dMMyyyy不起作用?
年份,或更準確地說是模式字母u,y和Y,在 中是特殊的DateTimeFormatter.ofPattern()。對于其他數字欄位,四個模式字母表示寬度正好為 4 的欄位。對于年份,它表示最小欄位寬度為 4。這反過來破壞了在兩位數年份情況下作業的相鄰值決議。相反,我認為決議器貪婪地使用所有 7 或 8 位數字作為月份的第幾天,然后無法找到它們之后的一個月。
相鄰值決議使您的模式dMMyy起作用。當所有其他欄位具有固定寬度時,它基本上允許在它們之間沒有分隔符的一系列欄位中的第一個(并且僅是第一個)具有可變寬度。所以我們讓相鄰值決議再次起作用的技巧是讓 year 欄位的寬度固定為 4。builder 的appendValue方法可以做到這一點。
那么為什么沒有yy作業yyyy呢?因為歲月很特別。yy表示固定寬度為 2。yyyy表示最小寬度為 4。
檔案報價和鏈接
從檔案DateTimeFormatter:
年份:字母數決定了使用填充的最小欄位寬度。如果字母數為兩個,則使用減少的兩位數形式。對于列印,這會輸出最右邊的兩位數字。對于決議,這將使用基值 2000 進行決議,從而生成 2000 到 2099 范圍內的年份。如果字母數少于四個(但不是兩個),則符號僅按 輸出負年份
SignStyle.NORMAL。否則,如果超過焊盤寬度,則按照 輸出符號SignStyle.EXCEEDS_PAD。
DateTimeFormatterDateTimeFormatterBuilder.appendValue(TemporalField, int)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/346068.html
上一篇:如何將ProjectExpression與帶空格的列名一起使用?
下一篇:如何解決這個JSON決議問題?
