Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么java SimpleDataFormat可以解析带有额外字符的格式化文本?_Java_Simpledateformat - Fatal编程技术网

为什么java SimpleDataFormat可以解析带有额外字符的格式化文本?

为什么java SimpleDataFormat可以解析带有额外字符的格式化文本?,java,simpledateformat,Java,Simpledateformat,我正在用MM dd yyyy HH:MM:ss格式解析用户输入的日期字符串,我发现12-20-2012 10:10:10 abcdexxxx也可以是pasred。这怎么会发生?这是我的密码: SimpleDateFormat df = new SimpleDateFormat( "MM-dd-yyyy HH:mm:ss" ); String currColValue = "12-20-2012 10:10:10 abcdexxxx"; try{ d=df.parse( currColVa

我正在用MM dd yyyy HH:MM:ss格式解析用户输入的日期字符串,我发现12-20-2012 10:10:10 abcdexxxx也可以是pasred。这怎么会发生?这是我的密码:

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());
}
但是没有例外,字符串值被解析为日期。为什么?

每:

解析给定字符串开头的文本以生成日期。该方法不能使用给定字符串的整个文本

强调我的

与上述评论的含义相反,这与宽松解析无关;相反,这只是因为此方法不打算使用整个字符串。如果您希望验证它是否使用了整个字符串,我想您可以设置一个ParsePosition对象,然后检查ParsePosition,看看它是否解析到字符串的末尾。

Per:

解析给定字符串开头的文本以生成日期。该方法不能使用给定字符串的整个文本

强调我的


与上述评论的含义相反,这与宽松解析无关;相反,这只是因为此方法不打算使用整个字符串。如果您希望验证它是否使用了整个字符串,我想您可以设置一个ParsePosition对象,然后检查ParsePosition,查看它是否解析到字符串的末尾。

检查SimpleDataFormat.parseString文档。它清楚地表明了这一点

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.

检查SimpleDataFormat.parseString文档。它清楚地表明了这一点

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.
java.time 我想提供一个现代的答案。这个问题是在java.time(现代java日期和时间API)问世的前一个月提出的,我们现在都应该使用它

    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处找到未分析的文本

与旧的SimpleDataFormat类相反,现代类的解析方法坚持解析整个字符串,如果您需要的话,可以只解析字符串的一部分。另外,请注意异常消息的准确性和清晰度。顺便说一句,SimpleDateFormat不仅早已过时,而且还出了名的麻烦。你只发现了许多令人惊讶的问题中的一个。我建议您不再使用SimpleDateFormat和Date

链接:解释如何使用java.time。

java.time 我想提供一个现代的答案。这个问题是在java.time(现代java日期和时间API)问世的前一个月提出的,我们现在都应该使用它

    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处找到未分析的文本

与旧的SimpleDataFormat类相反,现代类的解析方法坚持解析整个字符串,如果您需要的话,可以只解析字符串的一部分。另外,请注意异常消息的准确性和清晰度。顺便说一句,SimpleDateFormat不仅早已过时,而且还出了名的麻烦。你只发现了许多令人惊讶的问题中的一个。我建议您不再使用SimpleDateFormat和Date


链接:解释如何使用java.time。

我想使用方法重载,通过示例继续提供上述正确答案

public Date parse(String text, ParsePosition pos);
要解析整个字符串,只需创建一个索引为0的新ParsePosition对象,指示解析需要从begin开始,将其传递给方法,并在解析后检查其索引属性。 索引是解析结束的地方。如果与字符串长度匹配,则字符串从头到尾完全匹配

下面是一个单元测试来演示它

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;
    }
}

我想用重载方法举例说明上述正确答案

public Date parse(String text, ParsePosition pos);
要解析整个字符串,只需创建一个索引为0的新ParsePosition对象,指示解析需要从begin开始,将其传递给方法,并在解析后检查其索引属性。 索引是解析结束的地方。如果与字符串长度匹配,则字符串从头到尾完全匹配

下面是一个单元测试来演示它

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;
    }
}

你看过setLenient吗?看过。我将其设置为false并仍在分析中。您是否查看了setLenient的可能副本?是的。我将其设置为false并仍在分析中。可能重复Yes。现在我们正在使用JDK1.8,我更喜欢使用LocalDate/LocalDateTime/DateTimeFormatter。。。但我不能使用这个版本后,它刚刚发布。是的。现在我们正在使用JDK1.8,我更喜欢使用LocalDate/LocalDateTime/DateTimeFormatter。。。但我不能使用这个版本后,它刚刚发布。