Parsing a date string using java.text.SimpleDateFormat
Asked Answered
M

7

0

I have a weird problem, I need to parse a date string that looks like 1997-02-14T00:00:00.0000000+05:30. The odd thing about the date string is the time zone information. It's +05:30 instead of the usual +0530.

I have the basic format string ready, yyyy-MM-dd'T'HH:mm:ss.SSSSSSSZ which would have worked like a charm, if not for the TZ information.

Can anyone suggest a solution to this problem? Is there some kind format string which can handle that kind of TZ info?

Thanks in advance.

Megan answered 12/10, 2009 at 14:15 Comment(2)
Contrary to your second sentence, +05:30 is not a time zone. That text is an offset from UTC. A time zone has a name in format of Continent/Region such as Europe/Paris or Asia/Kolkata.Doiron
There is nothing odd about +05:30 with a COLON character (:) versus +0530. Quite the opposite, as I have seen multiple libraries that expect the COLON character to be present despite the international standard ISO 8601 making it optional. So I recommend always including the COLON.Doiron
F
3

Can you not preprocess with a regex and replace the timezone e.g.

String dateAndTime = ...
String preprocessed = dateAndTime.replace("([+-])(\\d\\d):(\\d\\d)$", "$1$2$3");
// Go on with your life 
Firefly answered 12/10, 2009 at 14:23 Comment(0)
A
5

I've looked into this problem myself several month ago. If I remember correctly, SimpleDateFormat isn't flexible enough to accept other timezone formats (mine was +530). What I did was a simple pre-processing step - i.e. try to remove the colon before passing the String to SimpleDateFormat.

Antifreeze answered 12/10, 2009 at 14:21 Comment(0)
F
3

Can you not preprocess with a regex and replace the timezone e.g.

String dateAndTime = ...
String preprocessed = dateAndTime.replace("([+-])(\\d\\d):(\\d\\d)$", "$1$2$3");
// Go on with your life 
Firefly answered 12/10, 2009 at 14:23 Comment(0)
C
3

Java 8+

The most appropriate type to prase 1997-02-14T00:00:00.0000000+05:30 into is OffsetDateTime. Note that java.time API is based on ISO 8601 and therefore you do not need to specify a DateTimeFormatter to parse a date-time string which is already in ISO 8601 format.

import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.ZonedDateTime;

class Main {
    public static void main(String[] args) {
        String strDateTime = "1997-02-14T00:00:00.0000000+05:30";
        OffsetDateTime odt = OffsetDateTime.parse(strDateTime);
        System.out.println(odt);

        // Technically, you can also parse it into a ZonedDateTime but a ZonedDateTime
        // is supposed to contain ZoneId along with ZoneOffset
        System.out.println(ZonedDateTime.parse(strDateTime));

        // With Java 12+, it is also possible to parse it into an Instant
        System.out.println(Instant.parse(strDateTime));
    }
}

Output:

1997-02-14T00:00+05:30
1997-02-14T00:00+05:30
1997-02-13T18:30:00Z

Learn more about the modern Date-Time API from Trail: Date Time.

Just for the sake of completeness

The java.util Date-Time API and their formatting API, SimpleDateFormat are outdated and error-prone. Since the release of Java-8 (Mar 2014), it is highly recommended to stop using them completely and switch to the modern Date-Time API. However, for any reason, if you want to stick to the legacy API, you can use SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSSSSXXX") to parse your string.

class Main {
    public static void main(String[] args) throws ParseException {
        String strDateTime = "1997-02-14T00:00:00.0000000+05:30";
        DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSSSSXXX");
        Date date = sdf.parse(strDateTime);
        System.out.println(date);
    }
}

Output:

Thu Feb 13 18:30:00 GMT 1997
Criticism answered 22/12, 2022 at 14:3 Comment(0)
A
2

SimpleDateFormat should accept this. From the doc:

For parsing, general time zones are also accepted.

and these are specified as:

GMTOffsetTimeZone:
             GMT Sign Hours : Minutes

which looks like what you have ?

If that fails, then the Joda DateTimeFormat claims to do this. I would be tempted to use Joda regardless, for a whole range of reasons (a more consistent and simpler API, thread-safety for formatters/parsers etc.)

Absorptivity answered 12/10, 2009 at 14:21 Comment(4)
I've just tested it, but it doesn't work: new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss z").parse("Wed, 4 Jul 2001 12:08:56 -07:00")Antifreeze
What happens if (say) you have GMT-07:00 (I appreciate that's not what you currently have)Absorptivity
Yes, it works after prepending GMT to the timezone ("Wed, 4 Jul 2001 12:08:56 GMT-07:00"). But given the format from the question, this (using 'z' instead of 'Z' in format string) still isn't a viable way to parse those dates.Antifreeze
Yes. Agreed. You may want to check out Joda (for this and other time/date issues)Absorptivity
M
2

Is this by chance a date string that comes from an XML file (ISO8601 format)? Unfortunately there is no (easy) way to parse this with SimpleDateFormat, exactly due to the ':' in the timezone part that SimpleDateFormat has no way to deal with properly.

Have a look at my answer in this other question about how to parse XML datetime strings.

Mcginnis answered 12/10, 2009 at 14:22 Comment(0)
A
2

Of course, there is always the hack of preprocessing your String.

If nobody finds a better answer, that would be something already. You could encapsulate it in a method, with a comment to explain the hack.

Allomorphism answered 12/10, 2009 at 14:22 Comment(0)
M
0

I think it should use the replaceAll method of the String for regular expression.

String dateAndTime = ...
String preprocessed = dateAndTime.replaceAll("(GMT)([+-])(\\d\\d):(\\d\\d)", "$2$3$4");
Malodorous answered 15/9, 2010 at 8:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.