Reputation: 645
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
Reputation: 340300
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 );
To determine if your input string was invalid, catch IllegalArgumentException
.
You can even get a java.util.Date back out if need be.
java.util.Date date = dateTime.toDate();
Upvotes: 0
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
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
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
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