强制SimpleDateFormat解析整个字符串

时间:2015-09-25 07:58:24

标签: java date parsing datetime

我的日期字符串格式如下:"dd/MM/yyyy HH:mm:ss"。我想从中创建一个Date对象,并且我正在使用SimpleDateFormat类。我们的应用程序接受存储在String数组中的许多不同日期格式。我们所做的是遍历该数组,使用applyPattern到我们的SimpleDateFormat对象并尝试parse给定的日期字符串。如果它抛出异常,我们在数组中尝试下一个日期格式等。

但是我发现parse类的SimpleDateFormat方法并不一定要尝试解析整个字符串。如果它从字符串的某些部分成功创建了一个Date对象,那么它将返回它。这里的问题是我们给定的日期字符串包含日期和时间数据,但在我们的第一次parse尝试中SimpleDateFormat使用更简单的模式:"dd/MM/yyyy"。并且因为在解析过程中它在给定的日期字符串中找到匹配日期,所以它在那里停止并创建一个没有时间信息的Date对象。

有没有办法强制SimpleDateFormat解析它给出的整个字符串?

String dateString = "01/01/2015 05:30:00";
Date date = null;
for (String format : Constants.DATE_FORMATS) {//String Array that contains many date format strings.
    try {
        simpleDateFormat.applyPattern(format);//First format applied is "dd/MM/yyyy".
        date = simpleDateFormat.parse(dateString);
        //No exception thrown it accepts the "dd/MM/yyyy" part of the dateString even though the string itself contains even more data.
    }
    catch (Exception e) {}
}
//Returns a date object with the time set to 00:00:00

4 个答案:

答案 0 :(得分:1)

您可以通过提供ParsePosition来检查解析了多少输入。 parse方法更新位置以告诉您解析了多少。

ParsePosition pos = new ParsePosition(0);
date = simpleDateFormat.parse(dateString, pos);

if (pos.getIndex() < dateString.length()) {
    // did not parse all of dateString
}

答案 1 :(得分:0)

我认为没有办法强制SimpleDateFormat解析整个String,但你可以比较格式的长度和输入的长度

String[] formats = new String[] {"dd/MM/yyyy", "dd/MM/yyyy HH:mm:ss"};
String input = "25/09/2015 10:25:31";
Date result = null;

for (String format: formats) {
    if (input != null && format.length() == input.length()) {
        try {
            SimpleDateFormat sdFormat = new SimpleDateFormat(format);
            result = sdFormat.parse(input);
            break;
        }
        catch (ParseException e) {
        }
    }
}

修改 另一种方法是使用JodaTime来解析String。

String[] formats = new String[] { "dd/MM/yyyy", "dd/MM/yyyy HH:mm:ss" };
String input = "25/09/2015 10:25:31";
LocalDateTime result = null;

for (String format : formats) {
    try {
        DateTimeFormatter sdFormat = DateTimeFormat.forPattern(format);
        result = sdFormat.parseLocalDateTime(input);
        break;
    }
    catch (IllegalArgumentException e) {
    }
}
System.out.println(result);

Date resultDate = result.toDate();
System.out.println(resultDate);

这会给你

2015-09-25T10:25:31.000
Fri Sep 25 10:25:31 CEST 2015

答案 2 :(得分:0)

您可以使用类似的内容而不是Behavior

EllipseMorph(BorderedMorph) initialize

如果您解析的字符串与模式的长度不同,则会抛出异常。这应该阻止SimpleDateFormat解析import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; class StrictDateFormat extends SimpleDateFormat { private String pattern; public void applyPattern(String pattern) { super.applyPattern(pattern); this.pattern = pattern; } @Override public Date parse(String source) throws ParseException { if (source.length() != pattern.length()) { throw new ParseException("Wrong size", pattern.length()); } return super.parse(source); } } 。这个将始终严格,而不仅仅是"01/01/2015 05:30:00"

答案 3 :(得分:0)

对于那些想要获得java.util.Date对象并避免使用第三方库的人,我使用了答案的压缩版本:

for (String format : Constants.DATE_FORMATS) {
        try {
            return Date.from(LocalDateTime.parse(dateString, DateTimeFormatter.ofPattern(format)).atZone(ZoneId.systemDefault()).toInstant());
        } catch (DateTimeParseException e) {}
    }

使用此代码块,它将使用正确的格式,使用java 8自己的java.time库,该库可以正确匹配格式。别忘了添加try-catch块! IDE不会要求它,因为DateTimeParseException是一个运行时异常但我们想要处理它以便进入下一个循环迭代。