1

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"
2
  • 4
    Have you tried with HH:mm:ss'Z'")? Commented Oct 29, 2012 at 14:58
  • Your code is still broken, see my answer below. Commented Oct 29, 2012 at 15:04

5 Answers 5

4

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.

Sign up to request clarification or add additional context in comments.

2 Comments

That would work if the input always has a literal Z for the timezone, but there are also valid ISO 8601 date strings where the timezone is something else than Z - so the validation wouldn't work for all valid ISO 8601 date strings.
@Jesper, You are correct. You need to try multiple patterns to see what happens or do some fixup like replaceLast("Z$", "+0:00") or rely on the Java7 pattern that you noted.
2

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.

Comments

1

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");.

Comments

1

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.

6 Comments

+1 for ISO8601_FORMAT.setTimeZone(DateUtils.UTC_TIME_ZONE);
Since Java 7, there's a new code that can be used in date formats for SimpleDateFormat, the code X, which matches the ISO 8601 time zone.
-1 since the toJava method will fail both if the string does not contain a milliseconds field and if the time zone differs from 'Z'.
Unfair downvote, as you can see, this class is intended for JSON interaction. So contract has to be kept in JS.
@Michael-O: In which case, it does not answer the question asked.
|
0

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();

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.