鉴于:
String validInput = "2023-12-31";
String lenientInput = "2023-12-31 "; // Extra space
DateTimeFormatter strictFormatter = new DateTimeFormatterBuilder()
.appendPattern("yyyy-MM-dd")
.parseStrict()
.toFormatter();
DateTimeFormatter lenientFormatter = new DateTimeFormatterBuilder()
.appendPattern("yyyy-MM-dd")
.parseLenient()
.toFormatter();
LocalDate strictDate = LocalDate.parse(validInput, strictFormatter);
System.out.println("Strict: " + strictDate); //OK WORKS
LocalDate lenientDate = LocalDate.parse(lenientInput, lenientFormatter);
System.out.println("Lenient: " + lenientDate); // 但失败了
我无法理解
parseStrict()
与 parseLenient()
之间的确切区别。
我尝试了很多模式,发现“宽松”和“严格”似乎没有什么区别。
parseLenient()
的作用是什么?我可以使用什么模式才能将 LocalDate.parse("2023-12-31 ", whatFormatterToUseHere)
解析为 2023 年 12 月 31 日?
编辑:-
DateTimeFormatterBuilder dfb=new DateTimeFormatterBuilder();
dfb.parseLenient();
dfb.appendPattern("MMyydd");
String s="092430";
System.out.println(dfb.toFormatter().parse(s));
为什么我会得到
java.time.format.DateTimeParseException: Text '092430' could not be parsed at index 6
API 有点不幸;对于两个“完全”不相关的概念,“严格与宽松”的概念出现了两次。 越界宽大处理
在严格模式下,将这些单独的值解析为单个日期会失败,因为 2024 年 2 月 30 日不存在。在宽松模式下,解析器会捏造它并最终生成一个 LocalDate,它是 2024-02-29 或 2024-03-01 (我不确定是哪一个;如果你关心的话,这非常表明你不希望宽松从这个意义上来说)。
但这根本不是parseLenient()
所做的;为了得到你使用
withResolverStyle(ResolverStyle.LENIENT)
.
字段解析宽松parseLenient()
MMM
时“02”是否为有效值(假设
MMM
表示:月份作为文本
而 02 不是文本?) 在您的代码片段中,您误解了
parseLenient()
的作用 并且您误解了如何使用它。
如何运作 您在parseLenient()
之前
致电
appendPattern
。它会修改所有进一步的 append
调用。
parseStrict()
根本不执行任何操作(因为严格是默认值),除了
作为“取消设置”宽松模式的一种方式。你可以这样做:
DateTimeFormatter lenientFormatter = new DateTimeFormatterBuilder()
.parseLenient()
.appendPattern("yyyy-")
.parseStrict()
.appendPattern("MM-dd")
.toFormatter();
这将为您提供一个格式化程序,它可以宽松地解析年份(以及分隔年份和月份的破折号),然后解析月份、日期以及严格分隔它们的破折号。调用 parseLenient()
然后调用 toFormatter()
不会执行任何操作。
它有什么作用它并没有像你想象的那样做。即使您向上移动
parseLenient()
在严格模式下,如果将月份部分配置为文本,那么在解析月份时必须采用文本形式。在宽松模式下,如果是数字就好了。
DateTimeFormatter lenientFormatter = new DateTimeFormatterBuilder()
.parseLenient()
.parseCaseInsensitive()
.appendPattern("yyyy-MMM-dd")
.toFormatter(Locale.ENGLISH);
System.out.println(LocalDate.parse("2024-Feb-20", lenientFormatter));
System.out.println(LocalDate.parse("2024-02-20", lenientFormatter));
DateTimeFormatter strictFormatter = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.appendPattern("yyyy-MMM-dd")
.toFormatter(Locale.ENGLISH);
System.out.println(LocalDate.parse("2024-Feb-20", strictFormatter));
System.out.println(LocalDate.parse("2024-02-20", strictFormatter));
MMM
表示您需要文本月份,而不是数字月份。在宽松模式下,这并不重要,在严格模式下,这并不重要,并且 2024-02-20
无法解析。无论你设置得多么宽松,
LocalDate.parse("2024-02-20 ", lenientFormatter)
都会失败。解决这个问题的最佳方法就是简单地将它们.trim()
去掉,而不是试图想出一个处理它的模式。