How to sanity check a date in Java

2018-12-31 14:15发布

I find it curious that the most obvious way to create Date objects in Java has been deprecated and appears to have been "substituted" with a not so obvious to use lenient calendar.

How do you check that a date, given as a combination of day, month, and year, is a valid date?

For instance, 2008-02-31 (as in yyyy-mm-dd) would be an invalid date.

17条回答
余欢
2楼-- · 2018-12-31 15:11

Two comments on the use of SimpleDateFormat.

it should be declared as a static instance if declared as static access should be synchronized as it is not thread safe

IME that is better that instantiating an instance for each parse of a date.

查看更多
听够珍惜
3楼-- · 2018-12-31 15:12

Assuming that both of those are Strings (otherwise they'd already be valid Dates), here's one way:

package cruft;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class DateValidator
{
    private static final DateFormat DEFAULT_FORMATTER;

    static
    {
        DEFAULT_FORMATTER = new SimpleDateFormat("dd-MM-yyyy");
        DEFAULT_FORMATTER.setLenient(false);
    }

    public static void main(String[] args)
    {
        for (String dateString : args)
        {
            try
            {
                System.out.println("arg: " + dateString + " date: " + convertDateString(dateString));
            }
            catch (ParseException e)
            {
                System.out.println("could not parse " + dateString);
            }
        }
    }

    public static Date convertDateString(String dateString) throws ParseException
    {
        return DEFAULT_FORMATTER.parse(dateString);
    }
}

Here's the output I get:

java cruft.DateValidator 32-11-2010 31-02-2010 04-01-2011
could not parse 32-11-2010
could not parse 31-02-2010
arg: 04-01-2011 date: Tue Jan 04 00:00:00 EST 2011

Process finished with exit code 0

As you can see, it does handle both of your cases nicely.

查看更多
浪荡孟婆
4楼-- · 2018-12-31 15:13

I think the simpliest is just to convert a string into a date object and convert it back to a string. The given date string is fine if both strings still match.

public boolean isDateValid(String dateString, String pattern)
{   
    try
    {
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        if (sdf.format(sdf.parse(dateString)).equals(dateString))
            return true;
    }
    catch (ParseException pe) {}

    return false;
}
查看更多
萌妹纸的霸气范
5楼-- · 2018-12-31 15:16

java.time

With the Date and Time API (java.time classes) built into Java 8 and later, you can use the LocalDate class.

public static boolean isDateValid(int year, int month, int day) {
    boolean dateIsValid = true;
    try {
        LocalDate.of(year, month, day);
    } catch (DateTimeException e) {
        dateIsValid = false;
    }
    return dateIsValid;
}
查看更多
姐姐魅力值爆表
6楼-- · 2018-12-31 15:19

The current way is to use the calendar class. It has the setLenient method that will validate the date and throw and exception if it is out of range as in your example.

Forgot to add: If you get a calendar instance and set the time using your date, this is how you get the validation.

Calendar cal = Calendar.getInstance();
cal.setLenient(false);
cal.setTime(yourDate);
try {
    cal.getTime();
}
catch (Exception e) {
  System.out.println("Invalid date");
}
查看更多
登录 后发表回答