当使用SimpleDateFormat解析字符串到日期时,我遇到了一个非常奇怪的行为.考虑以下单元测试:
@Test public void testParse() throws ParseException { DateFormat dateFormat = new SimpleDateFormat("yyyyMMdd"); String dateStr = "2012-12-21"; Date parsedDate = dateFormat.parse(dateStr); Calendar date = Calendar.getInstance(); date.setTime(parsedDate); Assert.assertEquals(2012,date.get(Calendar.YEAR)); Assert.assertEquals(11,date.get(Calendar.MONTH)); // yeah,Calendar sucks Assert.assertEquals(21,date.get(Calendar.DAY_OF_MONTH)); }
可以看出,上述代码中有一个有意的错误:SimpleDateFormat使用“yyyyMMdd”初始化,但要解析的字符串格式为“yyyy-MM-dd”.我会期望这样的事情会导致ParseException,或者至少在尽力而为的基础上正确解析.相反,由于某些奇怪的原因,日期被解析为2011-11-02.嗯?
这是不能接受的,因为一个单一的错误,而处理输入将导致一些完全意外/毁灭性的事情.在此期间切换到JodaTime,但要了解这里出了什么问题,那将是很好的.
解决方法
那么输入将被分为3个组件:年,月,日,你会得到月份= -12和日= -21(修正见下文).尝试解析2012/12/21,你会得到例外:)
编辑:摘自JavaDoc:
Month: If the number of pattern letters is 3 or more,the month is interpreted as text; otherwise,it is interpreted as a number.
编辑2:修正
看看SimpleDateFormat的源头,似乎2012-12-21实际上是分为:
year = "2012" month = "-1" day = "2-"
源注释表示a – 跟随一个数字可能表示一个负数(取决于语言环境)或是一个分隔符.在你的情况下,它似乎被视为一个分隔符,因此day =“2-”结果在day = 2,因此是11月的第二个.