Reputation: 63
I am trying to convert a String in the format of "Wed Jun 01 00:00:00 GMT-400 2016" to ISO8601 "2016-06-01T00:00:00.000Z". I am getting an error "Unparseable date". I am not sure what am I doing wrong.
DateFormat startDate = new SimpleDateFormat("EEE MMM dd HH:mm:ss 'GMT'Z yyyy", Locale.US);
startDate.setTimeZone(TimeZone.getTimeZone("Etc/UTC"));
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm'Z'", Locale.US);
formatter.setTimeZone(TimeZone.getTimeZone("Etc/UTC"));
Date aParsedDate = null;
try {
// give the date in that format
aParsedDate = (Date) startDate.parse(inputDateAsString);
System.out.println(aParsedDate.toString());
// convert Date to ISO8601
String nowAsISO = formatter.format(aParsedDate);
System.out.println("ISO date = " + nowAsISO);
return nowAsISO;
} catch (ParseException e) {
e.printStackTrace();
}
Upvotes: 2
Views: 552
Reputation: 79105
The ISO 8601 standard for timezone offset is to represent the HOUR with two digits. The separator for the HOUR and the MINUTE is optional. The MINUTE is also optional when it is zero. However, in your date-time string, Wed Jun 01 00:00:00 GMT-400 2016, the HOUR is of only one digit.
There is no OOTB (Out-Of-The-Box) DateTimeFormatter
defined for the pattern in which your date-time string, Wed Jun 01 00:00:00 GMT-400 2016 is. Luckily, java.time
, the modern date-time API provides you with a way to define/build parsing/formatting types with complex patterns.
Demo:
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
DateTimeFormatter dtf = new DateTimeFormatterBuilder()
.appendPattern("E MMM d H:m:s")
.appendLiteral(' ')
.appendZoneId()
.appendOffset("+Hmm", "")
.appendLiteral(' ')
.appendPattern("u")
.toFormatter(Locale.ENGLISH);
String strDateTime = "Wed Jun 01 00:00:00 GMT-400 2016";
OffsetDateTime odt = OffsetDateTime.parse(strDateTime, dtf);
System.out.println(odt);
}
}
Output:
2016-06-01T00:00-04:00
As you can see, for timezone offset, I have used the pattern, +Hmm
(one digit for HOUR and two for MINUTE).
Learn more about the modern date-time API from Trail: Date Time.
Note that the legacy date-time API (java.util
date-time types and their formatting type, SimpleDateFormat
) is outdated and error-prone. It is recommended to stop using it completely and switch to java.time
, the modern date-time API*.
For any reason, if you need to convert this object of OffsetDateTime
to an object of java.util.Date
, you can do so as follows:
Date date = Date.from(odt.toInstant());
* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.
Upvotes: 2