I am very sceptical about treating Z just as literal. The char Z has a meaning, namely zero offset. The documentation of Joda-Time version 1.6 says about this code:
String timestamp = "2014-09-23T23:03:11Z";
DateTime dt =
ISODateTimeFormat.dateTimeNoMillis().parseDateTime(timestamp).withZone(DateTimeZone.UTC);
System.out.println(dt); // 2014-09-23T23:03:11.000Z
Returns a formatter that combines a full date and time without millis,
separated by a 'T' (yyyy-MM-dd'T'HH:mm:ssZZ). The time zone offset is
'Z' for zero, and of the form '±HH:mm' for non-zero.
Now let's view at following four alternatives in detail (explicitly tested with version 1.6.2):
String timestamp = "2014-09-23T23:03:11Z";
DateTimeZone utc = DateTimeZone.UTC;
DateTime dt1 = ISODateTimeFormat.dateTimeNoMillis().parseDateTime(timestamp).withZone(utc);
System.out.println(dt1); // 2014-09-23T23:03:11.000Z (OK)
DateTime dt2 = new DateTime(timestamp, utc);
System.out.println(dt2); // 2014-09-23T23:03:11.000Z (OK)
DateTime dt3 =
DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss'Z'").parseDateTime(timestamp).withZone(utc);
System.out.println(dt3); //2014-09-23T21:03:11.000Z (WRONG!!!)
DateTime dt4 =
DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ssZZ").parseDateTime(timestamp).withZone(utc);
// exception: Invalid format: "2014-09-23T23:03:11Z" is malformed at "Z"
Conclusion: The other answers given so far treating Z as literal are wrong because the input is treated in local timezone, not with offset UTC+00:00. Use either the constructor or the specific class IsoDateTimeFormat
(I would prefer latter one for clarity).
About the exception: This is a bug solved with version 2.0, see release-notes. You should better update your library version.
Allow 'Z' and 'ZZ' in format patterns to parse 'Z' as '+00:00'
[2827359]