Question

I want to know is there a way to check the Java Date format to makes sure that a user doesn't enter a date like 56-13-2013 where the format is dd-MM-yyyy. Currently when I enter a date with 13 months it will carry over to add one year and then will display 1 month. E.g. 16-16-2013 will give me 16-04-2014.

Was it helpful?

Solution

Use setLenient to validate the input Date String

SimpleDateFormat format = new SimpleDateFormat("dd-MM-yyyy");
format.setLenient(false);
Date date = format.parse(myDateString);

OTHER TIPS

You haven't said how you're currently parsing the value - I assume it's with SimpleDateFormat. Just call setLenient(false) and that should validate the input.

For example:

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

public class Test {
    public static void main(String[] args) throws Exception {
        SimpleDateFormat format = new SimpleDateFormat("dd-MM-yyyy");
        // Prints a value in 2014
        System.out.println(format.parse("16-16-2013"));
        format.setLenient(false);
        // Throws an exception
        System.out.println(format.parse("16-16-2013"));        
    }
}

If you're doing any significant amount of work, I'd also highly recommend using Joda Time instead of the built-in classes.

java.time

The java.util Date-Time API and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern Date-Time API*.

Also, quoted below is a notice from the home page of Joda-Time:

Note that from Java SE 8 onwards, users are asked to migrate to java.time (JSR-310) - a core part of the JDK which replaces this project.

Solution using java.time, the modern Date-Time API:

This can be controlled by using the appropriate ResolverStyle that offers three different approaches, strict, smart and lenient. The smart option is the default which can resolve the day-of-month as long as it is in the range of 1-31, and month as long as it is in the range of 1-12.

Demo:

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

public class Main {
    public static void main(String[] args) {
        demonstrateResolverStyles("56-13-2013");
        demonstrateResolverStyles("29-02-2013");
        demonstrateResolverStyles("32-02-2013");
        demonstrateResolverStyles("28-13-2013");
    }

    static void demonstrateResolverStyles(String input) {
        System.out.println("Input string: " + input);
        try {
            System.out.println("Parsed using ResolverStyle.LENIENT => " + LocalDate.parse(input,
                    DateTimeFormatter.ofPattern("d-M-u", Locale.ENGLISH).withResolverStyle(ResolverStyle.LENIENT)));
        } catch (DateTimeParseException e) {
            System.out.println(e.getMessage());
        }

        try {
            // Default is ResolverStyle.SMART
            System.out.println("Parsed using ResolverStyle.SMART => "
                    + LocalDate.parse(input, DateTimeFormatter.ofPattern("d-M-u", Locale.ENGLISH)));
        } catch (DateTimeParseException e) {
            System.out.println(e.getMessage());
        }

        try {
            System.out.println("Parsed using ResolverStyle.STRICT => " + LocalDate.parse(input,
                    DateTimeFormatter.ofPattern("d-M-u", Locale.ENGLISH).withResolverStyle(ResolverStyle.STRICT)));
        } catch (DateTimeParseException e) {
            System.out.println(e.getMessage());
        }
        System.out.println();
    }
}

Output:

Input string: 56-13-2013
Parsed using ResolverStyle.LENIENT => 2014-02-25
Text '56-13-2013' could not be parsed: Invalid value for MonthOfYear (valid values 1 - 12): 13
Text '56-13-2013' could not be parsed: Invalid value for MonthOfYear (valid values 1 - 12): 13

Input string: 29-02-2013
Parsed using ResolverStyle.LENIENT => 2013-03-01
Parsed using ResolverStyle.SMART => 2013-02-28
Text '29-02-2013' could not be parsed: Invalid date 'February 29' as '2013' is not a leap year

Input string: 32-02-2013
Parsed using ResolverStyle.LENIENT => 2013-03-04
Text '32-02-2013' could not be parsed: Invalid value for DayOfMonth (valid values 1 - 28/31): 32
Text '32-02-2013' could not be parsed: Invalid value for DayOfMonth (valid values 1 - 28/31): 32

Input string: 28-13-2013
Parsed using ResolverStyle.LENIENT => 2014-01-28
Text '28-13-2013' could not be parsed: Invalid value for MonthOfYear (valid values 1 - 12): 13
Text '28-13-2013' could not be parsed: Invalid value for MonthOfYear (valid values 1 - 12): 13

ONLINE DEMO

Learn more about the modern Date-Time API from Trail: Date Time.


* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top