2017-07-17 77 views
4
import java.text.ParseException; 

public class Hello { 

    public static void main(String[] args) throws ParseException { 
     System.out.println(new java.text.SimpleDateFormat("yyyy-MM-dd").parse("23-06-2015")); 
    } 
} 

为什么这会返回Sun Dec 05 00:00:00 GMT 28我期待着一个例外。为什么SimpleDateFormat不会为无效格式引发异常?

+0

您无法从格式化状态的字符串日期获取日期对象。因此,当你试图格式化日期时,无论你的格式如何,JVM都给你一个通用的日期。 – Anant666

+0

尝试它:'java.time.format.DateTimeFormatter.ofPattern(“yyyy-MM-dd”)。parse(“23-06-2015”);',如果您使用的是Java8。 – sndyuk

+0

因为'SimpleDateFormat'是这样设计的。事实证明这是一个糟糕的设计决定。如果您在解析之前在'SimpleDateFormat'上调用'setLenient(false)',您可能会得到预期的异常。但是最好的解决方案是@sndyuk建议的方法:完全跳过'SimpleDateFormat'并使用'DateTimeFormatter'。如果你还没有使用Java 8,你可以在[ThreeTen Backport](http://www.threeten.org/threetenbp/)中找到它。 –

回答

6

SimpleDateFormat的Javadoc有这样说的重复模式字母:

号码:格式化,模式字母的数量是最小位数,和更短的数字是零填充到这个数额。 用于解析,除非它需要两个相邻场

(重点煤矿)

所以分离解析的模式字母的数量被忽略"yyyy-MM-dd"相当于"y-M-d"

使用此模式,"23-06-2015"被解析为year = 23, month = 6, dayOfMonth = 2015

默认情况下,得到由六月0023开始于1日和转发计数2015天,带你到12月5日解决0028.

你可以用SimpleDateFormat.setLenient(false)改变这种行为 - 与宽大相禁用,它会抛出超范围数字的例外。这是正确记录在Calendar.setLenient()


注意,新的代码在Java中8,这是为了避免老DateCalendar类是一个好主意。如果可以,请使用LocalDateTime.parse(CharSequence text, DateTimeFormatter formatter)

+2

此外,如果要阅读'DateFormat'类中'parse'方法的JavaDoc,您可以看到下面的内容:*默认情况下,解析是宽松的:如果输入不在此对象的格式方法使用的表单中,但仍然可以解析作为日期,然后解析成功。客户可以通过调用setLenient(false)来坚持严格遵守格式。* –

+1

谢谢@AlexChermenin - 将用此更新。 – slim

+0

非常感谢。 – Amit

相关问题