检查字符串是否仅包含日期

时间:2015-02-02 07:23:51

标签: java date date-format

我有一个字符串,可以包含各自格式的日期(yyyy-MM-dd)或日期和时间(yyyy-MM-dd HH:mm:ss)。

我想知道哪些字符串只包含日期。

DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
System.out.println(dateFormat.parse("2015-02-02"));
System.out.println(dateFormat.parse("2015-02-02 23:23:23"));

在上面的代码中,两个字符串都被成功解析,而格式只有第一个。

4 个答案:

答案 0 :(得分:3)

我会使用parse的重载来获取ParsePosition - 之后您可以检查位置:

import java.util.*;
import java.text.*;

public class Test {

    public static void main(String[] args) throws Exception {
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        dateFormat.setLenient(false);
        System.out.println(parseFully(dateFormat, "2015-02-02"));
        System.out.println(parseFully(dateFormat, "2015-02-02 23:23:23"));
    }

    private static Date parseFully(DateFormat format, String text) 
          throws ParseException {
        ParsePosition position = new ParsePosition(0);
        Date date = format.parse(text, position);
        if (position.getIndex() == text.length()) {
            return date;
        }
        if (date == null) {
            throw new ParseException("Date could not be parsed: " + text,
                                     position.getErrorIndex());
        }
        throw new ParseException("Date was parsed incompletely: " + text,
                                 position.getIndex());
    }
}

答案 1 :(得分:2)

public static void main(String[] args) {
        String dateOnly = "2015-02-02";
        String dateAndTimeOnly = "2015-02-02 23:23:23";
        System.out.println("Date Only = " + validateDateFormat(dateOnly));
        System.out.println("Date And time Only = " + validateDateFormat(dateAndTimeOnly));
    }

    public static boolean validateDateFormat(String input) {

        return input.matches("([0-9]{4})-([0-9]{2})-([0-9]{2})");
    }

<强>输出

Date Only = true
Date And time Only = false

正则表达式是自解释的 - 输入将由-分隔,ist部分([0-9]{4})可以包含4位数,第二部分可以包含2位数[0-9]{2},因此为第3位。

答案 2 :(得分:1)

java.time

java.util 日期时间 API 及其格式化 API SimpleDateFormat 已过时且容易出错。建议完全停止使用它们并切换到 modern Date-Time API*

使用 java.time(现代日期时间 API)的解决方案:

让我们首先尝试按照您的方式进行操作:

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        String[] arr = { "2015-02-02", "2015-02-02 23:23:23" };
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd", Locale.ENGLISH);

        for (String s : arr) {
            System.out.println("Attempting to parse '" + s + "':");
            LocalDate date = LocalDate.parse(s, dtf);
            System.out.println("Parsed successfully: " + date);
        }
    }
}

输出:

<块引用>

正在尝试解析“2015-02-02”:
解析成功:2015-02-02
试图解析 '2015-02-02 23:23:23':
线程“main”中的异常 java.time.format.DateTimeParseException: Text
'2015-02-02 23:23:23' 无法解析,在索引 10 处找到未解析的文本

如您所见,java.time API 会正确抛出异常,通知您有关问题。另一方面,SimpleDateFormat 会以静默方式解析导致您发布的问题的输入字符串。

因此,使用现代日期时间 API,您有两个简单的选择:

  1. 只需捕获异常并说明第二个输入(即 2015-02-02 23:23:23)不是指定日期模式的日期字符串。
  2. 使用函数 DateTimeFormatter#parse(CharSequence, ParsePosition),并将 ParsePosition 索引设置为 0

下面给出了第二个选项的演示:

import java.text.ParsePosition;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        String[] arr = { "2015-02-02", "2015-02-02 23:23:23" };
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd", Locale.ENGLISH);

        for (String s : arr) {
            ParsePosition pp = new ParsePosition(0);
            LocalDate.from(dtf.parse(s, pp));
            if (pp.getIndex() < s.length()) {
                System.out.println("'" + s + "' is not a date string as per the specified date pattern.");
            }
        }
    }
}

输出:

<块引用>

'2015-02-02 23:23:23' 不是指定日期模式的日期字符串。

ONLINE DEMO

注意: Never use SimpleDateFormat or DateTimeFormatter without a Locale

Trail: Date Time 了解有关现代 Date-Time API 的更多信息。


* 出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,您可以使用 ThreeTen-Backport,它将大部分 java.time 功能向后移植到 Java 6 & 7. 如果您正在为 Android 项目工作并且您的 Android API 级别仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaringHow to use ThreeTenABP in Android Project

答案 3 :(得分:0)

达到所需的format后,SimpleDateFormat不会格式化其余String。这就是你解析第二个字符串的原因。

这篇文章SimpleDateFormat parse(string str) doesn't throw an exception when str = 2011/12/12aaaaaaaaa?可能会对您有所帮助。

同时检查java docs中的DateFormat#parse方法