我很困惑为什么SimpleDateFormat
无法正确解析以下输入数据。
我试图在String
上测试各种可能允许的日期格式,看看它是否会使用其中一种格式正确解析。
注意:我使用的其他不正确的日期格式报告了解析错误。这就是我期望看到的。
我做错了什么?或者,我可以做什么作为解决方法?
String dformat = "MM-dd-yyyy";
String cDate = "2013-12-28";
SimpleDateFormat f = new SimpleDateFormat(dformat);
Date dd = f.parse(cDate);
结果是成功。解析的日期是:
日期9月12日星期五00:00:00太平洋标准时间195
嗯,日期应该是 2013年12月28日。 在这种情况下,我希望看到(就像我看到的其他无效格式):
java.text.ParseException: Unparseable date: "2013-12-28"
答案 0 :(得分:2)
您应该考虑使用java.util.Date的新java 8版本,即java.time.LocalDate和java.time.LocalDateTime作为SDK的一部分。由于您遇到问题,这些Date API被认为更稳定。这是一个例子。
String armisticeDate = "2013-12-28";
LocalDate aLD = LocalDate.parse(armisticeDate);
System.out.println("Date: " + aLD);
String armisticeDateTime = "2013-12-28T11:50";
LocalDateTime aLDT = LocalDateTime.parse(armisticeDateTime);
System.out.println("Date/Time: " + aLDT);
如果您想创建不同的格式,可以执行以下操作。
String anotherDate = "04 Apr 2016";
DateTimeFormatter df = DateTimeFormatter.ofPattern("dd MMM yyyy");
LocalDate random = LocalDate.parse(anotherDate, df);
System.out.println(anotherDate + " parses as " + random);
有关完整文档,请查看Oracle页面。
https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html
答案 1 :(得分:2)
要收到错误消息:
java.text.ParseException: Unparseable date: "2013-12-28"
你需要打电话:
f.setLenient(false);
正如parse(String source, ParsePosition pos)
的javadoc所说:
默认情况下,解析是宽松的:如果输入不是此对象的格式方法使用的形式,但仍可以解析为日期,则解析成功。客户可以通过致电
setLenient(false)
坚持严格遵守格式。
答案 2 :(得分:1)
您的代码应该是这样的:
String dformat = "yyyy-MM-dd";
String cDate = "2013-12-28";
SimpleDateFormat f = new SimpleDateFormat(dformat);
Date dd = f.parse(cDate);
您的问题中的日期格式有误。
答案 3 :(得分:1)
dformat不符合cDate格式。因此,您必须在dformat中提供cDate,或者您必须在"" yyyy-MM-dd"
中更改dformat答案 4 :(得分:1)
您的格式模式和日期字符串不多。 改为:
String dformat = "yyyy-MM-dd";
答案 5 :(得分:1)
嗯,SimpleDateFormat
已知为problematic and bugged class,lots of strange behaviours。
可能发生的事情类似于问题described in this article。考虑你的模式和输入:
MM-dd-yyyy
2013-12-28
它可能在本月读作" 20",日为" 3"和#34; -28"? (或者其他一些值,因为我不确定它如何将2-28
解释为4位数字)。而这个混乱的最终结果是一个完全错误,奇怪的日期 - 并且不要问我它是如何达到最终结果的,这对我来说是一个谜。
无论如何,当模式与输入格式不匹配时会发生这种情况,并且SimpleDateFormat
读取的实际值将是不可预测的并且有点违反直觉。但真正重要的是这个课程有很多问题和设计缺陷,而且默认情况下它很宽松,所以它试图成为聪明的"在发出错误之前做了很多奇怪的事情。
如果要验证输入,只需按照Andreas的建议调用f.setLenient(false)
即可关闭宽松模式。当输入与模式不匹配时,这将抛出异常。
但是,如果你正在使用Java 8,那么你应该使用java.time API,这是非常优越的,它解决了SimpleDateFormat
所带来的许多问题。
要检查字符串是否包含特定格式的日期,请使用java.time.format.DateTimeFormatter
。默认情况下,此类不宽容为SimpleDateFormat
,因此它应该按预期工作:
// use the format "month-day-year"
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("MM-dd-yyyy");
// try to parse a string in a different format (year-month-day)
LocalDate dt = LocalDate.parse("2013-12-28", fmt); // exception
上面的代码尝试创建一个LocalDate
,一个代表日期(只有日,月和年)的类。但是,如果您只想验证输入(不将其分配给任何变量),您只需使用格式化程序:
fmt.parse("2013-12-28"); // exception