-6

I have the below String which contains multiple dates; something like this:

I was born on 8/11/1965. I need to change all the dates into a different format.

What is the best optimized way to achieve this ?

Note:

I have not asked someone to give me the code; only asking for suggestions; hence cant see any reason for the negative rating.

user182944
  • 7,897
  • 33
  • 108
  • 174
  • It's impossible with regex. – Avinash Raj Jul 30 '14 at 15:19
  • Please suggest the alternative way then...have not tried yet; just need suggestions to start with – user182944 Jul 30 '14 at 15:20
  • 2
    Your guess is wrong, use a date parsing module. – hwnd Jul 30 '14 at 15:21
  • @hwnd Can you please elaborate your answer? It will be really helpful – user182944 Jul 30 '14 at 15:22
  • @BackSlash Have not tried anything yet, hence posted this for getting some suggestions to start with. I have never asked anyone for any ready-made code, I will do it my own way...only need some suggestions to start with and thats it :) – user182944 Jul 30 '14 at 15:24
  • @AvinashRaj Please explain why not possible. – user182944 Jul 30 '14 at 15:26
  • 1
    If the format of the dates is unknown, this is going to be impossible. What do you intend to do with 12/12/12? Getting dates in a typical format with regex, and parsing them and formatting them with date formatters is possible. – David Conrad Jul 30 '14 at 15:27
  • How come a regex alone detects the corresponding day? – Avinash Raj Jul 30 '14 at 15:29
  • @DavidConrad Thanks a lot for your explanation. Can you please suggest what should be the optimized approach for this? – user182944 Jul 30 '14 at 15:29
  • 1
    @user182944 I think the downvotes are for not showing your attempts and not completing your question to make it a question helpful to future readers. – Unihedron Jul 30 '14 at 15:52
  • possible duplicate of [Java string to date conversion](http://stackoverflow.com/questions/4216745/java-string-to-date-conversion) – Basil Bourque Jul 30 '14 at 16:13
  • 1
    Searching StackOverflow for "java date format" returns thousands of hits; perhaps the reason for the down-votes. Anyways, read the answers on the duplicate question I posted in above comment. Focus on [Joda-Time](http://www.joda.org/joda-time/) and [java.time](http://docs.oracle.com/javase/8/docs/api/java/time/package-summary.html) as the old java.util.Date & .Calendar classes are bad for you mental health. Little need for regex as those two excellent date-time libraries can do the heavy lifting for you. – Basil Bourque Jul 30 '14 at 16:20
  • 1
    The regex would be used only to extract the dates from the text, and to replace them with the formatted dates. Joda-Time and java.time are not going to parse the dates out of an English sentence for you, or do the replacement. – David Conrad Jul 30 '14 at 17:29

2 Answers2

2

This is the complete algorithm.

Pattern ddpat = Pattern.compile( "\\d{1,2}/\\d{1,2}/\\d{4}" );
DateFormat dddf = new SimpleDateFormat("dd/MM/yyyy");
DateFormat wwdf = new SimpleDateFormat("EEEE, MMMM d yyyy");
String s = "I was born on 18/11/1965. and completed my grad on 9/10/1978 and so on";
StringBuilder sb = new StringBuilder();
Matcher ddmat = ddpat.matcher( s );
int offset = 0;
while( ddmat.find( offset ) ){
    int beg = ddmat.start();
    int end = ddmat.end();
    String dd = s.substring( beg, end );
    String ww = wwdf.format( dddf.parse( dd ) );
    sb.append( s.substring( offset, beg ) ).append( ww );
    offset = end;
}
sb.append( s.substring( offset ) );
System.out.println( sb.toString() );

To handle 99/99/9999 and similar, handle ParseException after dddf.parse( dd ) and replace with whatever you seem fit. Strings not matching the regex are hopeless, unless you can think of a regex matching "false dates". ;-)

Later

If you want to fish for several formats:

Pattern ddpat = Pattern.compile( "(\\d{1,2}/\\d{1,2}/\\d{4})|(\\d{4}-\\d{2}-\\d{2})" );
DateFormat[] dddf = new DateFormat[]{
    new SimpleDateFormat("dd/MM/yyyy"),
    new SimpleDateFormat("yyyy-MM-dd") };
DateFormat wwdf = new SimpleDateFormat("EEEE, MMMM d yyyy");
String s = "I was born on 18/11/1965. and completed my grad on 1978-10-09 and so on";
StringBuilder sb = new StringBuilder();
Matcher ddmat = ddpat.matcher( s );
int offset = 0;
while( ddmat.find( offset ) ){
    for( int ig = 1; ig <= ddmat.groupCount(); ig++ ){
    if( ddmat.group(ig) != null ){
        int beg = ddmat.start(ig);
        int end = ddmat.end(ig);
        String dd = s.substring( beg, end );
        String ww = wwdf.format( dddf[ig-1].parse( dd ) );
        sb.append( s.substring( offset, beg ) ).append( ww );
        offset = end;
        break;
    }
    }
}
sb.append( s.substring( offset ) );
System.out.println( sb.toString() );
laune
  • 31,114
  • 3
  • 29
  • 42
  • 1
    I just see that I have used "d" instead of "dd". This is because I find leading zeros in the days of the month in a verbalized date "bureaucratic style". YMMV. – laune Jul 30 '14 at 15:52
  • Thanks for the sample code. What I am planning is to use an OR i.e. `|` with a series of date patterns in the regex. IS it a good idea? Any help on that please? – user182944 Jul 30 '14 at 15:53
  • 1
    @user182944 Not an "||", but you can use "|". You will have to try and convert using several DateFormats. It's possible that using individual groups will tell you the format, and then you know the DateFormat. – laune Jul 30 '14 at 15:57
  • No, knowing the date format is not possible, hence trying to find out different options. Can you suggest any other alternative other than using a `|` ? – user182944 Jul 30 '14 at 16:00
  • @user182944 Make up your mind! Either you know a number of possible formats, or you don't. If you know regex patterns, you know date formats. -- See the updated answer. – laune Jul 30 '14 at 16:04
  • Yes correct - I totally agree with you. If the format is known then `Regex` is the option to look at. Suppose the format is not known, then what will be the most optimized way to achieve this? Can you please help on this? – user182944 Jul 30 '14 at 16:07
  • @user182944 See [Skynet](https://en.wikipedia.org/wiki/Skynet_%28Terminator%29). – Elliott Frisch Jul 30 '14 at 16:08
1

If I understand your objective, the easiest approach I can think of is using two SimpleDateFormat instances. One for your input format, one for your output format. That is, something like -

String str = "8/11/1965";
DateFormat in = new SimpleDateFormat("dd/MM/yyyy");
DateFormat out = new SimpleDateFormat("EEEE, MMMM dd yyyy");
System.out.println(out.format(in.parse(str)));

Output is (because November 8, 1965 is a Monday not a Wednesday) -

Monday, November 08 1965

$ cal 11 1965
   November 1965      
Su Mo Tu We Th Fr Sa  
    1  2  3  4  5  6  
 7  8  9 10 11 12 13  
14 15 16 17 18 19 20  
21 22 23 24 25 26 27  
28 29 30              
Elliott Frisch
  • 198,278
  • 20
  • 158
  • 249
  • Thanks for the reply. Formatting part is fine for me, the part causing problem is there are different kinds of Date Format included in the `String`. How to handle that? Please suggest – user182944 Jul 30 '14 at 16:02
  • 2
    [laune](http://stackoverflow.com/users/2107876/laune) already answered that [here](http://stackoverflow.com/a/25041227/2970947). Your question still isn't clear in terms of recognizing dates in multiple formats... that's an ambiguous endeavor. – Elliott Frisch Jul 30 '14 at 16:06