gpt4 book ai didi

java - DateTimeFormatter 无效日期在 LocalDateTime.parse 之后得到调整

转载 作者:行者123 更新时间:2023-12-04 14:27:52 27 4
gpt4 key购买 nike

这个问题在这里已经有了答案:





Java 8 LocalDateTime is parsing invalid date

(5 个回答)


4年前关闭。




我一直在努力解决 java 8 如何处理将字符串解析为 LocalDateTime 的实例的问题。 .我在为从 String 到 LocalDateTime 的转换编写单元测试时注意到了这一点。 .

下面是一个方法示例(不是实际的),自从 java 8 发布以来我已经使用了一段时间。

private void convertToLocalDateTime(String s) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-M-d HH:mm")
.withResolverStyle(ResolverStyle.STRICT);
try {
LocalDateTime ldt = LocalDateTime.parse(s, formatter);
System.out.println("s: " + s + " -> ldt: " + ldt.toString());
} catch(DateTimeParseException e) {
System.out.println("s: " + s + " -> The field is not a valid date.");
}
}

在这里,你可以看到我添加了两个 s.o.p是为了向您展示显示器。这是一个显示示例;
s: 2016-06-31 11:00 -> ldt: 2016-06-30T11:00
s: 2016-07-31 11:00 -> ldt: 2016-07-31T11:00
s: 2016-08-31 11:00 -> ldt: 2016-08-31T11:00
s: 2016-09-31 11:00 -> ldt: 2016-09-30T11:00
s: 2016-10-31 11:00 -> ldt: 2016-10-31T11:00
s: 2016-11-31 11:00 -> ldt: 2016-11-30T11:00
s: 2016-12-31 11:00 -> ldt: 2016-12-31T11:00
s: 2016-11-0 11:00 -> The field is not a valid date.
s: 2016-11-1 11:00 -> ldt: 2016-11-01T11:00
s: 2016-11-15 11:00 -> ldt: 2016-11-15T11:00
s: 2016-11-30 11:00 -> ldt: 2016-11-30T11:00
s: 2016-11-31 11:00 -> ldt: 2016-11-30T11:00
s: 2016-11-32 11:00 -> The field is not a valid date.

如您所见,一切似乎都是正确的,但是天数为 1 天的日期不正确(例如 11 月 31 日)被转换为 30 十一月。我很困惑,因为我一直在使用这种方法,今天我才注意到。

经过一番研究,我发现有一种“解析器风格”。这是来自 java doc 的文字

public static DateTimeFormatter ofPattern(String pattern) Creates a formatter using the specified pattern. This method will create a formatter based on a simple pattern of letters and symbols as described in the class documentation. For example, d MMM uuuu will format 2011-12-03 as '3 Dec 2011'.

The formatter will use the default FORMAT locale. This can be changed using withLocale(Locale) on the returned formatter Alternatively use the ofPattern(String, Locale) variant of this method.

The returned formatter has no override chronology or zone. It uses SMART resolver style.



我就像“wut”。显然,有 three resolver styles : 严格、聪明和宽容。

所以,我选择了 STRICT . convertToLocalDateTime(String) 正文中的第一行方法修改为
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-M-d HH:mm")
.withResolverStyle(ResolverStyle.STRICT);

然而,这给出了以下
s: 2016-01-31 11:00 -> The field is not a valid date.
s: 2016-02-31 11:00 -> The field is not a valid date.
s: 2016-03-31 11:00 -> The field is not a valid date.
s: 2016-04-31 11:00 -> The field is not a valid date.
s: 2016-05-31 11:00 -> The field is not a valid date.
s: 2016-06-31 11:00 -> The field is not a valid date.
s: 2016-07-31 11:00 -> The field is not a valid date.
s: 2016-08-31 11:00 -> The field is not a valid date.
s: 2016-09-31 11:00 -> The field is not a valid date.
s: 2016-10-31 11:00 -> The field is not a valid date.
s: 2016-11-31 11:00 -> The field is not a valid date.
s: 2016-12-31 11:00 -> The field is not a valid date.
s: 2016-11-0 11:00 -> The field is not a valid date.
s: 2016-11-1 11:00 -> The field is not a valid date.
s: 2016-11-15 11:00 -> The field is not a valid date.
s: 2016-11-30 11:00 -> The field is not a valid date.
s: 2016-11-31 11:00 -> The field is not a valid date.
s: 2016-11-32 11:00 -> The field is not a valid date.

这些突然都行不通了。即使使用 yyyy-MM-dd HH:mm没有帮助。我怀疑 STRICT 不能很好地处理自定义格式字符串......

所以,我的问题是:有没有办法克服“11 月 31 日”的问题,确实如此 不是 解决到11月30日? (和其他可能的日期类似)或者如果解析器调整了值,则返回 false 的方法?

或者我必须评估结果 LocalDateTime例如我自己?

最佳答案

你的困惑是有道理的。我发现实际上是一个 DateTimeFormatter用于图案 "yyyy-MM-dd HH:mm" ,使用 STRICT解析器样式,甚至拒绝它自己格式化的日期字符串。

经进一步调查,这似乎与DateTimeFormatter有关。的新(相对于完善的 java.text.SimpleDateFormat )区分“年份”和“时代”。与 DateTimeFormatter , 'y'格式符号代表后者;前者对应格式字母'u' .事实证明,如果我使用格式字符串 "uuuu-MM-dd HH:mm"您的程序产生了您似乎正在寻找的输出:

private void convertToLocalDateTime(String s) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-M-d HH:mm")
.withResolverStyle(ResolverStyle.STRICT);
try {
LocalDateTime ldt = LocalDateTime.parse(s, formatter);
System.out.println("s: " + s + " -> ldt: " + ldt.toString());
} catch(DateTimeParseException e) {
System.out.println("s: " + s + " -> The field is not a valid date.");
}
}

一位数与两位数的字段对解析没有影响。

This question解决“年份”和“年代”之间的区别。虽然我理解这种区别,但我认为实现 DateTimeFormatter 是一个糟糕的选择。与 SimpleDateFormat 的这种不必要的不​​兼容用于一些最常见的用途。我想我会交换 'u'的意思和' y ',从而避免您遇到的那种问题。然而,很明显,这个 API 的设计者不同意,这就是桥下的水。

关于java - DateTimeFormatter 无效日期在 LocalDateTime.parse 之后得到调整,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41679360/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com