我正在使用MM-dd-yyyy HH:mm:ss
格式从用户输入解析日期字符串,我发现12-20-2012 10:10:10 abcdexxxx
也可以被删除。怎么会发生这种情况?这是我的代码:
SimpleDateFormat df = new SimpleDateFormat( "MM-dd-yyyy HH:mm:ss" );
String currColValue = "12-20-2012 10:10:10 abcdexxxx";
try{
d=df.parse( currColValue );
}catch( ParseException e ){
System.out.println("Error parsing date: "+e.getMessage());
}
但没有例外,String值被解析为Date。为什么呢?
答案 0 :(得分:10)
每the Javadoc of the parse
method:
解析来自 给定字符串开头的文本以生成日期。 该方法可能不会使用给定字符串的整个文本。
(强调我的)。
与上述评论的含义相反,这与宽松解析无关;相反,只是这个方法并不打算消耗整个字符串。如果你想验证它是否消耗了整个字符串,我想你可以设置一个ParsePosition
对象和use the two-arg overload,然后检查ParsePosition
以查看它是否被解析到最后字符串。
答案 1 :(得分:2)
检查SimpleDateFormat.parse(String)doc。它清楚地说明了它。
Parses text from the beginning of the given string to produce a date. The method may not use the entire text of the given string.
http://docs.oracle.com/javase/7/docs/api/java/text/DateFormat.html#parse(java.lang.String)
答案 2 :(得分:1)
我想贡献现代的答案。在现代人Java日期和时间API java.time出来的前一个月就问了这个问题,我们现在都应该使用它。
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM-dd-yyyy HH:mm:ss");
String currColValue = "12-20-2012 10:10:10 abcdexxxx";
try {
LocalDateTime ldt = LocalDateTime.parse(currColValue, formatter);
// Do something with ldt
} catch (DateTimeParseException e) {
System.out.println("Error parsing date and time: " + e.getMessage());
}
输出:
错误分析日期和时间:无法分析文本'12 -20-2012 10:10:10 abcdexxxx',未分析文本位于索引19
与旧的SimpleDateFormat
类相反,现代类的parse
方法确实坚持解析整个字符串(如果您需要的话,可以仅解析部分字符串) 。还请注意异常消息的准确性和清晰度。顺便说一下,SimpleDateFormat
不仅早已过时,而且还非常麻烦。您仅发现它具有许多令人惊讶的问题之一。我建议您不再使用SimpleDateFormat
和Date
。
链接: Oracle tutorial: Date Time解释了如何使用java.time
。
答案 3 :(得分:0)
我想使用重载方法来举例说明上述正确答案
public Date parse(String text, ParsePosition pos);
要解析确切的整个字符串,只需创建一个新的ParsePosition对象(索引为0,指示解析需要从开始开始),将其传递给该方法,并在解析后检查其index属性。 索引是解析结束的地方。如果字符串长度匹配,则字符串从头到尾完全匹配。
这是一个演示它的单元测试
public class DateParseUnitTest {
@Test
public void testParse(){
Date goodDate = parseExact("2019-11-05");
Date badDate1 = parseExact("foo 2019-11-05");
Date badDate2 = parseExact("2019-11-05 foo");
assert(goodDate != null);
assert(badDate1 == null);
assert(badDate2 == null);
}
@Nullable
private Date parseExact(@NonNull String text){
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
ParsePosition pos = new ParsePosition(0);
Date date = formatter.parse(text, pos);
if (pos.getIndex() != text.length())
return null;
return date;
}
}