manisha chougule
manisha chougule

Reputation: 21

SetLenient(false) with Year

I am using DateFormat setLenient() to parse the string and validate the date. But I am not able to validate the year even if I am passing the wrong year like 2digits or 3digits year.Please tell me how to parse year for 4 digits only if i have given date through scanner.

    Scanner sc1 = new Scanner(System.in);
    System.out.println("enter date");
    String date1 = sc1.nextLine();
    String pattern="yyyy-MM-dd HH:mm:ss";
    DateFormat formatter= new SimpleDateFormat(pattern);
    formatter.setLenient(false);
    try {
         {
            formatter.parse(date1);
            System.out.println("valid date");
        }
    } catch (ParseException ex) {
        System.out.println("invalid date");
    }

Upvotes: 2

Views: 261

Answers (2)

Sweeper
Sweeper

Reputation: 273265

You should use DateTimeFormatter instead: DateTimeFormatter is a lot stricter in what strings are accepted and what are not.

DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
try {
    formatter.parse(date1);
    System.out.println("valid date");
} catch (DateTimeParseException ex) {
    System.out.println("invalid date");
}

setLenient doesn't really have much to do with whether years are two-digit or four-digit. "Lenient" here means the same thing as in Calendar. It is used to decide whether a date like 2019-01-32 would automatically become 2019-02-01, which I find to be rarely useful. If you would like this non-lenient SimpleDateFormat behaviour in DateTimeFormatter as well, you need to use:

String pattern = "uuuu-MM-dd HH:mm:ss";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern)
                                .withResolverStyle(ResolverStyle.STRICT);
try {
    LocalDateTime.parse(date1, formatter);
    System.out.println("valid date");
} catch (DateTimeParseException ex) {
    System.out.println("invalid date");
}

Upvotes: 2

Anonymous
Anonymous

Reputation: 86343

Range check

Charlemagne was born 2 April 742, and the year is usually given as three digits. I don’t think I have ever seen 0742. Would you require your user to enter it with a leading zero?

Maybe your problem is a different one: you don’t want to accept year 999 or earlier as input. For most applications that’s a good and valid restriction. If so, I’d consider: what is the valid range of dates? Not only how many digits should a year have (yyyy will also accept 5 or 6 digits).

So in addition to what @Sweeper says in the other answer (which has all the advantages: java.time, the modern Java date and time API is so much nicer to work with), do a range check. For example:

    final LocalDateTime minDateTime = LocalDateTime.of(1849, Month.DECEMBER, 22, 13, 30);
    final LocalDateTime maxDateTime = LocalDateTime.of(2032, Month.MAY, 5, 12, 0);
    String pattern = "uuuu-MM-dd HH:mm:ss";
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern)
            .withResolverStyle(ResolverStyle.STRICT);
    try {
        LocalDateTime dateTime = LocalDateTime.parse(date1, formatter);
        if (dateTime.isBefore(minDateTime) || dateTime.isAfter(maxDateTime)) {
            System.out.println("invalid date");
        } else {
            System.out.println("valid date");
        }
    } catch (DateTimeParseException ex) {
        System.out.println("invalid date");
    }

Upvotes: 1

Related Questions