2

I have the date validation code as below, it does not throw parseException for 01/01/19211.

What is the problem. Does anyone have alternate solution? I cannot use any third party libraries.

SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy");
        dateFormat.setLenient(false);
        try {
            resetPasswordUIBean.setDateOfBirth(dateFormat.parse(resetPasswordUIBean.getDateInput()));       
        } catch (ParseException e) {
            //handleException 
        }

Thanks a lot

RegisteredUser
  • 400
  • 7
  • 19
  • Note to future readers: You should not use `SimpleDateFormat` and `Date`. Use the modern Date and Time API available in the `java.time` package. [See Arvind's answer](https://stackoverflow.com/a/68293184/507738). – MC Emperor Jul 07 '21 at 21:38
  • Note that the input string `01/01/1921blah` [does not cause](https://ideone.com/V1JIsE) a `ParseException` to be thrown either, despite the invalid substring "blah". That is because the parsing completes when all pattern letters have been consumed, regardless of whether the whole text has been parsed. – MC Emperor Jul 07 '21 at 22:07

2 Answers2

3

There is no problem. It's accepting a valid date of the 1st of January 19211. I know it's not clear from the docs, but "yyyy" accepts more than 4 digits, for years beyond 9999.

If you want to restrict the date to some maximum year (e.g. not in the future, if this is meant to be a date of birth) then you can do so easily by finding out the year from the Date (via Calendar, of course). You probably want a minimum year as well. These are validation steps which make sense separately from parsing - basically there are plenty of dates which are valid as dates but aren't valid in your context.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • The date format is yyyy so technically it should not accept 19211(yyyyy), correct? – RegisteredUser Jun 06 '13 at 20:58
  • 1
    @RegisteredUser: It's not clear from the docs, to be honest - but I think *typically* parsers handle more than four digits for `yyyy`, and this seems to be the case here. I think it's reasonable, in order to handle both the "normal" case of a year up to 9999, but *also* handle later dates. Read my edited answer - you'd want to add more validation *anyway*. – Jon Skeet Jun 06 '13 at 21:00
  • I hope they have not designed it thinking their code will be used in year > 10000 :) – Alexandre Lavoie Jun 06 '13 at 21:19
1

A single y can parse the years of one+ digits

Caution: A two-digit year will be parsed as a year without a century e.g. 19 will be parsed as 0019. If you want it to be 2019, use yy.

Demo:

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

public class Main {
    public static void main(String[] args) {
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("M/d/y", Locale.ENGLISH);
        Stream.of(
                    "01/01/1",
                    "01/01/19",
                    "01/01/192",
                    "01/01/1921",
                    "01/01/19211"
        ).forEach( s -> System.out.println(LocalDate.parse(s, dtf)));
    }
}

Output:

0001-01-01
0019-01-01
0192-01-01
1921-01-01
+19211-01-01

ONLINE DEMO

Therefore, you need to get the value of the year from the resulting date and validate the year e.g.

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

public class Main {
    public static void main(String[] args) {
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("M/d/y", Locale.ENGLISH);
        int year = LocalDate.parse("01/01/19211", dtf).getYear();
        if (year < 1900 || year > 9999) {
            // Do this
        } else {
            // Do that
        }
    }
}

You may also like to check prefer u to y.

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

Note: 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*.


* 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.

Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110