-2

I am working on a date app where user will enter date and i am validating that date. Date format is dd/MM/yyyy. This is my code

import java.util.*;
import java.text.SimpleDateFormat;
import java.text.ParseException;

public class HelloWorld {
  public static void main(String[] args) {
 //Scanner sc = new Scanner(System.in);
  String dat = "02/1/2018";
  try {
             SimpleDateFormat df = new SimpleDateFormat("dd/MM/yyyy");
                df.setLenient(false);
                df.parse(dat);
                System.out.print("valid");
            } catch (ParseException e) {
                System.out.print("invalid");
            }

   }
 }

This is working perfect and validating my date but when i enter my date like 22/02/2-19 that also come as valid. But it should be invalid because my year is 2-19.

Harpreet Singh
  • 999
  • 9
  • 19
  • 1
    I recommend you avoid the `SimpleDateFormat` class. It is not only long outdated, it is also notoriously troublesome. Today we have so much better in [`java.time`, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/). – Ole V.V. Aug 11 '18 at 15:49

3 Answers3

2

java.time

You are using terrible old date-time classes that were supplanted years ago by the java.time classes.

For a date-only value, use a date-only class: LocalDate.

Define your formatting pattern with the DateTimeFormatter class. Search Stack Overflow for many more discussions and examples, as this has been covered many many times.

When parsing, trap for DateTimeParseException to determine if invalid.

String input = "22/02/2-19";
DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd/MM/uuuu" );
LocalDate ld = null;
try {
    ld = LocalDate.parse( input , f );
    System.out.println( "VALID: " + ld.toString() );
} catch ( DateTimeParseException e ) {
    System.out.println( "INVALID: " + input );
    e.printStackTrace();
}

INVALID: 22/02/2-19

java.time.format.DateTimeParseException: Text '22/02/2-19' could not be parsed at index 6…


About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.

Where to obtain the java.time classes?

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
1

According to the javadoc for SimpleDateFormat:

For parsing, if the number of pattern letters is more than 2, the year is interpreted literally, regardless of the number of digits. So using the pattern "MM/dd/yyyy", "01/11/12" parses to Jan 11, 12 A.D.

This is why the input 22/02/2-19 does not throw a parsing exception. It takes the 2 as the year and ignores the rest.

D.B.
  • 4,523
  • 2
  • 19
  • 39
  • So can you please suggest any method to show this invalid? – Harpreet Singh Aug 11 '18 at 15:47
  • 1
    You should be able to find that answer by doing your own research. For example I was able to find [a question about this topic with many answers](https://stackoverflow.com/q/226910/3284624). – D.B. Aug 11 '18 at 16:21
0

java.time

Basil Bourque’s excellent answer is already giving the best solution to your problem. I am not repeating that. If using that answer you want to accept 1-digit month as in your first example, 02/1/2018, you should give only one M in the format pattern string. Then both 1 and 01 will be accepted. Similarly one d will accept both 2 and 02 for day of month.

What went wrong in your code

SimpleDateFormat reads as much as possible from your string to match the format pattern, but is happy not to read all of it. With your second example, 22/02/2-19, it parses 22/02/2 into a Date of Mon Jan 02 00:00:00 CET 2 (exact result depending on your time zone), which is more than 2016 years ago. Since this is a valid date, it doesn’t throw any exception. It then ignores the last three characters of the string.

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161