Parsing different date formats in a string in Java

16,447

Solution 1

Use SimpleDateFormat.setLenient(false). This way it will not attempt to parse dates that aren't the exact format it wants.

Solution 2

Instead of testing "yyyy-MM-dd", then "yyyy/MM/dd", then "yyyy.MM.dd" (used in many countries), etc., you can start by

token = token.replaceAll("-|\\.", "/");

This way all dots and dashes are replaced with "/", and you can reduce the number of formats and tries.

Solution 3

You need to have all formats in the date_formats array for the type of format you anticipate would be coming in.

Have a look at the SimpleDateFormat javadocs.

Have a look at the examples in the javadocs.

2001-01-05      - yyyy-MM-dd 
2001/01/05      - yyyy/MM/dd
01/05/2001      - dd/MM/yyyy 
01-05-2001      - dd-MM-yyyy 
2001 january 5  - yyyy MMMMM d
2001 5 january  - yyyy d MMMMM
january 5 2001  - MMMMM d yyyy 
5 january 2001  - d MMMMM yyyy
january 5       - MMMMM d
5 january       - d MMMMM
Share:
16,447
Alagappan Ramu
Author by

Alagappan Ramu

Software Developer! 💻 Amateur photographer! 📷 Runner!🏃 Traveler! 🌍 NIT Trichy & SUNY Buffalo Alum! Delhi - Chennai - New York - San Diego

Updated on June 19, 2022

Comments

  • Alagappan Ramu
    Alagappan Ramu almost 2 years

    I have a string which can possibly contain a date in any of the following formats:

    2001-01-05 (yyyy-mm-dd)
    2001/01/05 (yyyy/mm/dd)
    01/05/2001 (dd/mm/yyyy)
    01-05-2001 (dd-mm-yyyy)
    2001 january 5
    2001 5 january
    january 5 2001
    5 january 2001
    january 5
    5 january
    

    I want to be able to parse the particular string and extract the Date object from it.

    My approach was as follows:

    String[] date_formats = {
                                "yyyy-MM-dd",
                                "yyyyy/MM/dd", 
                                "dd/MM/yyyyy",
                                "dd-MM-yyyy",
                                "yyyy MMM dd",
                                "yyyy dd MMM",
                                "dd MMM yyyy",
                                "dd MMM",
                                "MMM dd",
                                "dd MMM yyyy"};
    
    String output_date = null;
    for (String formatString : date_formats)
    {
         try
         {    
             Date mydate = new SimpleDateFormat(formatString).parse(token);
             SimpleDateFormat outdate = new SimpleDateFormat("yyyyMMdd");
             output_date = outdate.format(mydate);
             break;
         }
         catch (ParseException e) {
             System.out.println("Next!");
         }
     }
    

    This doesn't seem to work as expected. Especially for dates like 5 January 2001 etc. How do I go about doing this?

  • Alagappan Ramu
    Alagappan Ramu over 10 years
    I did have a look the docs. Aren't the patterns that I mentioned correct?
  • JHS
    JHS over 10 years
    Yes. Your formats are wrong. I have added the formats you need.
  • Alagappan Ramu
    Alagappan Ramu over 10 years
    It still doesn't work properly for dates like 5 January 2001. It first satisfies the yyyy MMM dd pattern and the date I end up getting is 00100624 which is totally arbitrary.
  • Arnaud Denoyelle
    Arnaud Denoyelle over 10 years
    Good to know but useless in this case. The OP is trying each format in a try/catch statement until the end of the try statement is met.
  • Kayaman
    Kayaman over 10 years
    @ArnaudDenoyelle Useless? His problem was that in some cases the non-correct patterns were parsing the values, giving arbitrary values. A situation corrected by setting lenient to false.
  • Arnaud Denoyelle
    Arnaud Denoyelle over 10 years
    IMHO, incorrect pattern will end in the catch statement and the next one will be tried.
  • Alagappan Ramu
    Alagappan Ramu over 10 years
    @ArnaudDenoyelle This has helped me in avoiding false positives when I parse the dates.
  • Arnaud Denoyelle
    Arnaud Denoyelle over 10 years
    OK, I had a confusion about the meaning of lenient. +1 for Kayaman.
  • Alagappan Ramu
    Alagappan Ramu over 10 years
    Setting setLenient to false as suggested by Kayaman, helped in avoiding the above error.
  • JHS
    JHS over 10 years
    But your list of "date_formats" should not have MMM. There is no date in your "possibility" list (example list) to match it.
  • Alagappan Ramu
    Alagappan Ramu over 10 years
    Okay... But, there are possibilities of the date being "5 Jan 2013", will the patter n "d MMMMM yyyy" be able to parse it?