mtical
mtical

Reputation: 329

Java Date Parsing "a.m." and "p.m."

Using SimpleDateFormat, how can you parse the String: "2013-05-23T09:18:07 p.m..380+0000"

All my SimpleDateFormat Strings are tripping up on the "p.m." part.

Thanks in advance.

EDIT: We have no control over the format coming in.

I've tried:

"yyyy-MM-dd'T'HH:mm:ss a.a..SSSZ"

"yyyy-MM-dd'T'HH:mm:ss aaaa.SSSZ"

"yyyy-MM-dd'T'HH:mm:ss a.'m'..SSSZ"

"yyyy-MM-dd'T'HH:mm:ss a.'m.'.SSSZ"

"yyyy-MM-dd'T'HH:mm:ss a.'m..'SSSZ"

"yyyy-MM-dd'T'HH:mm:ss aa'm'..SSSZ"

"yyyy-MM-dd'T'HH:mm:ss aa'm.'.SSSZ"

"yyyy-MM-dd'T'HH:mm:ss aaa'..'SSSZ"

"yyyy-MM-dd'T'HH:mm:ss aaa.'.'SSSZ"

"yyyy-MM-dd'T'HH:mm:ss aaa'.'.SSSZ"

Upvotes: 4

Views: 7224

Answers (4)

dhalsim2
dhalsim2

Reputation: 963

Here's a implementation using Java 8's new java.time package, so you can ditch java.util.Date and java.text.SimpleDateFormat:

import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.ChronoField;
import java.util.HashMap;
import java.util.Map;

public class Test {
    public static void main(String[] args) {
        String text = "2013-05-23T09:18:07 p.m..380+0000";
        Map<Long, String> map = new HashMap<>();
        map.put(0L, "a.m.");
        map.put(1L, "p.m.");
        DateTimeFormatter formatter = new DateTimeFormatterBuilder()
                .appendPattern("yyyy-MM-dd'T'hh:mm:ss ")
                .appendText(ChronoField.AMPM_OF_DAY, map)
                .appendPattern(".SSSZ").toFormatter();
        OffsetDateTime dateTime = OffsetDateTime.parse(text, formatter);
        System.out.println(dateTime);
    }
}

Running it yields:

2013-05-23T21:18:07.380Z

Upvotes: 2

Menelaos
Menelaos

Reputation: 26299

Just remove the p.m. part via string manipulation. It is redundant.

Than use a simple SimpleDateFormat to do the parsing.

Something along these lines:

String whatever = "2013-05-23T09:18:07 p.m..380+0000";
        whatever = whatever.replaceAll(" p.m..", ":").replaceAll(" a.m..", ":");
        System.out.println(whatever);

        S   

        String pattern = "yyyy-MM-dd'T'hh:mm:ss:SSS'Z'";

        SimpleDateFormat format = new SimpleDateFormat(pattern, Locale.US);
        Date date;
        try {
            date = format.parse(whatever);
             System.out.println(date);
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

Update

As pointed about by IAN, I missed out that the hours are not in 24hour format. I did however get the millisecond part correct, and added the timezone part to Jon Skeet's answer to get:

String text = "2013-05-23T09:18:07 p.m..380+0000";  
String pattern = "yyyy-MM-dd'T'hh:mm:ss aa'.'SSSZ";
SimpleDateFormat format = new SimpleDateFormat(pattern);

DateFormatSymbols symbols = format.getDateFormatSymbols();
symbols = (DateFormatSymbols) symbols.clone();
symbols.setAmPmStrings(new String[] { "a.m.", "p.m."});
format.setDateFormatSymbols(symbols);

Date date = format.parse(text);
System.out.println(date);

Upvotes: 0

malcolm the4
malcolm the4

Reputation: 357

Do it like this

String time="2013-05-23T09:18:07 p.m..380+0000";
        int index1=time.indexOf("");
        int index2 = time.indexOf(".."); // or you can give p.m. as argument if you want it to stop before pm

        String result = time.substring(index1,index2);
        System.out.print(result);

This has the following result

2013-05-23T09:18:07 p.m 

I hope this helps

Upvotes: 0

Jon Skeet
Jon Skeet

Reputation: 1502196

It's not clear what the "380+0000" part is meant to be, but you can fix the AM/PM part, by setting the DateFormatSymbols for the SimpleDateFormat. Here's an example:

import java.util.*;
import java.text.*;

public class Test {
    public static void main(String[] args) throws Exception {
        String text = "2013-05-23T09:18:07 p.m..380+0000";
        String pattern = "yyyy-MM-dd'T'hh:mm:ss aa'.380+0000'";

        SimpleDateFormat format = new SimpleDateFormat(pattern, Locale.US);
        format.setTimeZone(TimeZone.getTimeZone("UTC"));

        DateFormatSymbols symbols = format.getDateFormatSymbols();
        symbols = (DateFormatSymbols) symbols.clone();
        symbols.setAmPmStrings(new String[] { "a.m.", "p.m."});
        format.setDateFormatSymbols(symbols);

        Date date = format.parse(text);
        System.out.println(date);
    }
}  

I don't know whether you have to clone the DateFormatSymbols before mutating it - it's not clear, to be honest... the documentation points two ways:

DateFormatSymbols objects are cloneable. When you obtain a DateFormatSymbols object, feel free to modify the date-time formatting data. For instance, you can replace the localized date-time format pattern characters with the ones that you feel easy to remember. Or you can change the representative cities to your favorite ones.

Given that it's mentioning cloning, that suggests you should clone - but then the subsequent paragraph suggests not :(

Upvotes: 13

Related Questions