To answer the question as asked in the title, What is wrong with this Java date formatter?
EEEE
is for full name of the day of the week like Monday
. For the abbreviation like Mon
you need either E
, EE
or EEE
.
- As others have said, lower case
hh
is for clock hour within AM or PM from 01
through 12
, so cannot parse your hour of 00
. And even if it could, it would not provide enough information for the time of day. For hour of day from 00
though 23
you need upper case HH
.
- There’s a more basic problem that Basil Bourque already mentioned in a comment: The result of parsing a time zone abbreviation like
COT
is generally undefined. While COT
may have only one definition, I don’t know, most of the most common abbreviations are ambiguous, and you don’t know what you get from parsing them.
- As has also been mentioned your formatter cannot be used for formatting a
LocalDateTime
. A LocalDateTime
hasn’t got any time zone. The formatter requires a time zone for the abbreviated time zone name, zzz
. You may either format a ZonedDateTime
, or you may modify the formatter to have an override zone using its withZone
method.
A tip: When you don’t know why parsing fails, try formatting the expected value with the same formatter and compare the result to the string you are trying to parse. Most often the difference will lead you on the right track. Like this:
ZonedDateTime val = ZonedDateTime.of(
2020, 11, 18, 0, 0, 0, 0, ZoneId.of("America/Bogota"));
DateTimeFormatter formatter
= DateTimeFormatter.ofPattern("EEEE MMM d hh:mm:ss zzz yyyy", Locale.US);
String toBeParsed = "Wed Nov 18 00:00:00 COT 2020";
String formatted = val.format(formatter);
System.out.println("String to be parsed: " + toBeParsed);
System.out.println("Formatted string: " + formatted);
Output:
String to be parsed: Wed Nov 18 00:00:00 COT 2020
Formatted string: Wednesday Nov 18 12:00:00 COT 2020
The difference are Wednesday
and 12
, so it seems the bugs in the pattern are at EEEE
and hh
.
Your string seems to come out of the toString
method of the outdated java.util.Date
class. To parse the string from there see one of the answers linked to at the bottom. Or still better, get hold of the Date
object, convert it to a modern Instant
using its toInstant
method and perform any further conversions from there. Or yet still better, stop using Date
completely.
Links
How to parse the result from Date.toString()
: