user1772643
user1772643

Reputation: 645

parse exception in java

I am trying to validate a string whether it is in ISO-8601 date or not, but it is throwing a parse exception, not sure where it is going wrong.

try {
    String s = "2007-03-01T13:00:00Z";
    SimpleDateFormat ft = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
    ft.setLenient(false);
    System.out.println(ft.format(ft.parse(s)));
} catch (ParseException e) {
    System.out.println(e.getMessage());
}

output is:

Unparseable date: "2007-03-01T10:00:00Z"

Upvotes: 1

Views: 2379

Answers (5)

Basil Bourque
Basil Bourque

Reputation: 340300

Joda-Time

FYI, if you used Joda-Time instead of the notoriously troublesome java.util.Date/Calendar classes, you could simply pass that ISO 8601 string straight into a DateTime constructor without the bother of a formatter. Joda-Time uses ISO 8601 as its defaults.

DateTimeZone timeZone = DateTimeZone.forID( "America/Montreal" );
DateTime dateTime = new DateTime( "2007-03-01T13:00:00Z", timeZone );

Validation

To determine if your input string was invalid, catch IllegalArgumentException.

java.util.Date

You can even get a java.util.Date back out if need be.

java.util.Date date = dateTime.toDate();

Upvotes: 0

Michael-O
Michael-O

Reputation: 18415

Your code does not work because the SDF is very limited ad was not aware of ISO 8601 at the time when it was written.

You can take this code:

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.commons.lang.time.DateUtils;

public final class JSONDateUtil {

    private static final DateFormat ISO8601_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");

    static  {
        ISO8601_FORMAT.setLenient(false);
        ISO8601_FORMAT.setTimeZone(DateUtils.UTC_TIME_ZONE);
    }

    public static String toJSON(Date date) {
        return ISO8601_FORMAT.format(date);
    }

    public static String toJSON(long millis) {
        return ISO8601_FORMAT.format(millis);
    }

    public static Date toJava(String date) {
        try {
            return ISO8601_FORMAT.parse(date);
        } catch (ParseException e) {
            return null;
        }
    }

}

Note the timezone, very important.

Upvotes: 1

Jesper
Jesper

Reputation: 207026

If you're using Java 7, use the following format string: "yyyy-MM-dd'T'HH:mm:ssXXX"

Note: X is a new code (added in Java 7) that matches ISO 8601 time zone strings; see the API documentation of SimpleDateFormat.

Upvotes: 2

jarnbjo
jarnbjo

Reputation: 34323

If you want to validate an arbitrary string, you cannot hardcode the "Z" time zone designator, as the validation would fail for a valid ISO8601 time stamp like e.g. "2007-03-01T13:00:00+01".

If you are using Java 6 or earlier, SimpleDateFormat will not support ISO8601 time zone encoding, so you cannot use it to validate time stamps either. With Java 7 or later, you can use new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX");.

Upvotes: 1

Mike Samuel
Mike Samuel

Reputation: 120586

I suspect that Z is being interpreted as a time zone so would match -0800 but not a literal Z so you could solve that by quoting: 'Z'.

getErrorOffset should tell you where the problem is.

Upvotes: 4

Related Questions