首先请注意,我在这里使用java6。
我正在尝试从可能采用不同格式的字符串中获取日期。 出于某种原因,我没有得到希望的ParseException ...
trying yyyyMMdd
trying yyyy/MM/dd
trying yyyy-MM-dd
Fri Apr 25 00:00:00 EST 1980
运行: java test1 1980-04-25
我希望得到:
trying yyyyMMdd Tue Dec 04 00:00:00 EST 1979
但是我只能得到:
sklearn
你知道怎么了吗?
答案 0 :(得分:4)
SimpleDateFormat在默认情况下宽大,即使给定日期的格式可能与其配置为解析的格式不匹配,也不会引发异常。您可以像这样设置它的宽松程度:
SimpleDateFormat dateFormat = new SimpleDateFormat(format);
dateFormat.setLenient(false);
通过这种方式,它将检查字符在该日期实际上是否有效。
答案 1 :(得分:1)
你知道怎么了吗?
这是SimpleDateFormat
确实很麻烦的地方之一。尝试使用模式1980-04-25
解析yyyyMMdd
时,它会按预期将1980
解析为年,然后将-0
解析为月,因为它应该是两个字符,然后是{{1 }}作为一个月的一天,即使它也应该是两个字符也是如此。它忽略了4
,因为它已经完成了解析。
具有标准设置的-25
也忽略了没有月份SimpleDateFormat
的事实。它取为0,所以是1980年1月之前的一个月,这就是为什么获得1979年12月。
-0
非常麻烦,而且SimpleDateFormat
的设计也很差。两者早已过时。我建议您不要使用Date
。曾经。
SimpleDateFormat
让我们尝试使用示例字符串:
private static final String[] dateFormats
= "yyyyMMdd,yyyy/MM/dd,yyyy-MM-dd,dd/MM/yyyy,dd-MM-yyyy,dd-MMM-yyyy,yyyy MM dd"
.split(",");
public static LocalDate parseAllDateFormats(String date) {
if (date == null) {
return null;
}
for (String format : dateFormats) {
try {
System.out.println("trying " + format);
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern(format, Locale.ENGLISH);
return LocalDate.parse(date, dateFormatter);
}
catch (DateTimeParseException e) {
// Ignore, try next format
}
}
return null;
}
预期输出:
System.out.println(parseAllDateFormats("1980-04-25"));
我正在使用java.time(现代Java日期和时间API)。与旧的日期时间类相比,使用它要好得多。现代trying yyyyMMdd
trying yyyy/MM/dd
trying yyyy-MM-dd
1980-04-25
可以将解析的值解析为三种样式的日期:严格,精明和宽松。 Smart是默认值,它只接受1到12之间的月份。此外,DateTimeFormatter
将坚持解析整个字符串,否则将引发异常。
与您的代码相比,我还做了一些小的修改。在大多数情况下,我将做成LocalDate.parse
的数组(而不是DateTimeFormatter
的数组),但是它不允许我打印String
,所以在这里没有。我在第一个trying yyyyMMdd
语句中加上了花括号。我在格式化程序上指定了语言环境,因为语言的月份缩写不同,并且我想控制使用哪种语言。我捕获了特定的if
,并添加了一条注释,为什么我忽略它,因为否则忽略异常是一件很不好的事情。在方法的底部,如果没有有效的格式,还应该考虑引发异常,而不是返回DateTimeParseException
。
请注意,我在这里一直使用java6。