5

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?

5
  • @Kayaman What is wrong with the patterns? docs.oracle.com/javase/7/docs/api/java/text/… Commented Oct 2, 2013 at 12:37
  • 1
    Always provide a locale to your date format when you want to parse date in a particular language. (new SimpleDateFormat("{format}", Locale.ENGLISH);) Commented Oct 2, 2013 at 12:46
  • @AlagappanRamu Nothing now that you fixed them. Commented Oct 2, 2013 at 12:52
  • @Kayaman It still doesn't work properly for dates like 5 January 2001. It satisfies the yyyy MMM dd pattern and the date I end up getting is 00100624 which is totally arbitrary. Commented Oct 2, 2013 at 12:57
  • This doesn't seem to work as expected. Do you get an exception or a date which does not seems good? An example would be appreciated. Commented Oct 2, 2013 at 13:03

8 Answers 8

6

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

Sign up to request clarification or add additional context in comments.

5 Comments

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.
@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.
IMHO, incorrect pattern will end in the catch statement and the next one will be tried.
@ArnaudDenoyelle This has helped me in avoiding false positives when I parse the dates.
OK, I had a confusion about the meaning of lenient. +1 for Kayaman.
1

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

6 Comments

I did have a look the docs. Aren't the patterns that I mentioned correct?
Yes. Your formats are wrong. I have added the formats you need.
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.
Setting setLenient to false as suggested by Kayaman, helped in avoiding the above error.
But your list of "date_formats" should not have MMM. There is no date in your "possibility" list (example list) to match it.
|
1

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.

Comments

0

Is this what you are looking for?

String[] date_formats = {
                        "y-M-d",
                        "y/M/d", 
                        "d/M/y",
                        "d-M-y",
                        "y M d",
                        "y d M",
                        "d M y",
                        "d M",
                        "M d",
                        "d M y"};

String output_date = null;
for (String formatString : date_formats)
{
     try
     {    
         SimpleDateFormat sf = new SimpleDateFormat(formatString);  
         output_date = "5 January 2001"; 
         Date yourDate = sf.parse(output_date);
         break;
     }
     catch (ParseException e) {
         System.out.println("Next!");
     }
 }

Comments

0

You can extract String of Date by using

String mydate = new SimpleDateFormat(formatString).format(new Date());

new Date() will return current day's date, you can change it to any date that you desire.

So if you change you code like this:

String[] date_formats = {
        "y-M-d",
        "y/M/d", 
        "d/M/y",
        "d-M-y",
        "y M d",
        "y d M",
        "d M y",
        "d M",
        "M d",
        "d M y"};

for (String formatString : date_formats)
    {
        String mydate = new SimpleDateFormat(formatString).format(new Date());
        System.out.println(mydate);
    }

You will end up with these:

2013-10-2
2013/10/2
2/10/2013
2-10-2013
2013 10 2
2013 2 10
2 10 2013
2 10
10 2
2 10 2013

Comments

0

Add this date format "dd MMMMM YYYY" for "5 January 2001"

Comments

0
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
    String dateInString = formatter.format(date);

    LOG.warn("date in String "+dateInString);

make Sure that MM is in capital

Comments

0

Kayamans answer works, this is what it looks like in a code snippet so you can easily test it for yourself (direct copy paste from my own code):

static String[] date_formats = {
        "yyyy-MM-dd",
        "yyyy/MM/dd",
        "dd/MM/yyyy",
        "dd-MM-yyyy",
        "yyyy MMM dd",
        "yyyy dd MMM",
        "dd MMM yyyy",
        "dd MMM yyyy"};

static String[] dates = {
        "21/02/2012",
        "21-02-2012",
        "21-2-2012",
        "21 Feb 2012",
        "Feb 21 2012",//will not be parsed
        "21 februari 2012" //Dutch
};

@Test
public void test(){
    for(String date : dates) {
        parseDate(date);
        System.out.print("----------------");
    }
}

private void parseDate(String token){
    Locale dutch = new Locale("nl", "NL");
    for (String formatString : date_formats)
    {
        try
        {
            SimpleDateFormat format = new SimpleDateFormat(formatString, dutch);
            format.setLenient(false);
            Date mydate = format.parse(token);
            System.out.println(mydate.toString());
            break;
        }
        catch (ParseException e) {
            System.out.println("Next!");
        }
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.