I want to convert the date string \"Fri Sep 21 15:23:59 CEST 2012\" to \"2012-09-21T15:23:59\" in Java. I tried this with SimpleDateFormat and the following code:
Four points:
SimpleDateFormat
.MM
in the pattern string is taken to mean a two digit month number; for a three letter month abbreviation you need MMM
. This is probably what got you the ParseException (though a wrong locale may also give you one).Y
s are for week year. This bug is prone to get unnoticed for long since week year and calendar year typically only differ a few days close to New Year. For calendar year you must use lowercase y
s.Here’s how to do with the new date and time classes:
String dateString = "Fri Sep 21 15:23:59 CEST 2012";
DateTimeFormatter input = DateTimeFormatter.ofPattern("EEE MMM d HH:mm:ss z uuuu",
Locale.ROOT);
try {
LocalDateTime date = LocalDateTime.parse(dateString, input);
System.out.println(date.toString());
} catch (DateTimeParseException dtpe) {
System.err.println(dtpe.getMessage());
}
This prints:
2012-09-21T15:23:59
Please fill in an appropriate locale instead of Locale.ROOT
. uuuu
is a signed year: 0 corresponds to 1 BC, -1 to 2 BC, etc. You may use yyyy
if you are sure the year is AD (the current era).
You will notice that your desired format comes right out of LocalDateTime.toString()
, no need for any explicit formating. There is an alternative, though:
ZonedDateTime date = ZonedDateTime.parse(dateString, input);
System.out.println(date.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
The advantage of using ZonedDateTime
rather than LocalDateTime
is it preserves the time zone information from the date string. If there’s any chance you will need this later, go for this option.
The difference between calendar year and week-based year is explained in the answers to this question.
If you cannot use or do not want to use the newer classes, the correct pattern string to use with SimpleDateFormat
is in Reimeus’ answer. I still recommend giving the locale explicitly, though, for example:
SimpleDateFormat input = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy",
Locale.UK);
Locale possibly isn’t needed for the output format since this contains no text/words, only numbers.
Use
"EEE MMM dd HH:mm:ss z YYYY"
Note 3 MMM
You can use:
SimpleDateFormat input = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy");