3

I am trying to parse the date in a particular custom format.

WEDNESDAY 25th JAN 2012 - 12:44:07 PM

like this..

I created a SimpleDateFormat for this..

SimpleDateFormat sdf = new SimpleDateFormat("EEEE DD MMM YYYY - HH:MM:SS aa" );

the problem is the literal for the days. it is coming like 25th, 23rd, 02nd.I am getting exception for this thing...

help how to overcome this problem.

Bhesh Gurung
  • 50,430
  • 22
  • 93
  • 142
karthik
  • 463
  • 1
  • 6
  • 16
  • D is day in year, d is day in month.. http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html – L7ColWinters Feb 01 '12 at 19:04
  • 3
    possible duplicate of [How do you format the day of the month to say "11th", "21st" or "23rd" in Java?](http://stackoverflow.com/questions/4011075/how-do-you-format-the-day-of-the-month-to-say-11th-21st-or-23rd-in-java) – kosa Feb 01 '12 at 19:04
  • The question isn't how to *output* "th", "st", or "rd"; but how to parse it out of a string. – nybbler Feb 01 '12 at 19:15
  • ya nybbler is correct that thread dont deal with what we mentioned here – karthik Feb 01 '12 at 19:41

4 Answers4

3

You can remove the literal for the day using a regex like this.

String dateString = "WEDNESDAY 25th JAN 2012 - 12:44:07 PM";
SimpleDateFormat format = new SimpleDateFormat("EEEEEEE dd MMM yyyy - HH:mm:ss aa", new Locale("EN"));
dateString = dateString.replaceAll("(.*[0-9]{1,2})(st|nd|rd|th)(.*)", "$1$3");
Date parsedDate = format.parse(dateString);

System.out.println(parsedDate);

(Ignore the Locale, i'm from somewhere else :) )

mtsz
  • 2,725
  • 7
  • 28
  • 41
  • nice work...dont know how the replace all that reg ex performs...can you explain it shortly.... – karthik Feb 01 '12 at 20:19
  • The three expressions in parentheses are capture groups. The first group captures arbitrary characters followed by 1 or 2 digits (everything before the day literal). The second group models all four possible day digits. The third group denotes everything which comes after the literal. In the replace string you glue together group 1 and 3. You basically replace the whole string by the first part and the third part concatenated. – mtsz Feb 01 '12 at 20:25
2

You could split the date string you're trying to parse into parts and remove the offending two letters in the following way:

String text = "WEDNESDAY 21st JAN 2012 - 12:44:07 PM";
String[] parts = text.split(" ", 3);  // we only need 3 parts. No need splitting more
parts[1] = parts[1].substring(0, 2);
String parseableText = String.format("%s %s %s", parts[0], parts[1], parts[2]);  
SimpleDateFormat sdf = new SimpleDateFormat("EEEE dd MMM yyyy - hh:mm:ss aa" );

try {
    java.util.Date dt = sdf.parse(parseableText);
} catch (ParseException e) {
    e.printStackTrace();
}

Your parse string had some errors in it as well. Case is important for the date and time ptterns. See the SimpleDateFormat javadoc for a reference.

nybbler
  • 4,793
  • 28
  • 23
  • nybbler you are making sub string? thats okay..but is there any option so that i can patternize it because its just two characters cant we use any wildcard characters? – karthik Feb 01 '12 at 19:30
  • @karthik Not that I know of. I suppose you could nest try..catches 3 deep to cover the 3 possibilities for the two characters, but that wouldn't be my approach. – nybbler Feb 01 '12 at 19:44
  • what i thought if we can provide constant values in the simpleDateFormat like this SimpleDateFormat sdf = new SimpleDateFormat("EEEE DD'th' MMM YYYY - HH:MM:SS aa" ); if we have only 'th' as the text as an example. i wondered why is there no way i can use wildcard characters because i can match with 'rd' or any other two characters instead of matching with only'th'. if there is option,we can go for substring...no issues – karthik Feb 01 '12 at 20:01
1

You are going to have to manually do it somehow.

e.g. A method as follows:

public static String makeItParseable(String dateStr) {
    if(dateStr.contains("st ")) {
        return dateStr.replace("st ", " ");
    } else if(dateStr.contains("nd ")) {
        return dateStr.replace("nd ", " ");
    } else if(dateStr.contains("rd ")) {
        return dateStr.replace("rd ", " ");
    } else {
        return dateStr.replace("th ", " ");
    }
}

And use it make the input string parseable:

String dateStr = "WEDNESDAY 1st JAN 2012 - 12:44:07 PM";
dateStr = makeItParseable(dateStr);
DateFormat dateFormat = new SimpleDateFormat("EEEE dd MMM yyyy - hh:mm:ss a");
Date date = dateFormat.parse(dateStr);
Bhesh Gurung
  • 50,430
  • 22
  • 93
  • 142
0

Add ".th" to the format string, following what people stated in this thread

How do you format the day of the month to say "11th", "21st" or "23rd" in Java? (ordinal indicator)

Community
  • 1
  • 1
Alfabravo
  • 7,493
  • 6
  • 46
  • 82
  • it can be any of the three 11th may come or 21st may come...but it will have only two characters any option – karthik Feb 01 '12 at 19:26
  • i dont think the thread which you stated concerns about the problem mentioned here – karthik Feb 01 '12 at 19:35
  • I think it does as it shows how to create a SDF format capable of handling the date string OP wants to parse. Now, in the thread people wants to format, you want to parse, nevertheless both want to use SDF properly with nth, 2nd, 3rd, etc... – Alfabravo Feb 01 '12 at 19:49