-2

I'm trying to format the date you see as a String in the below code, to be able to have it as a LocalDateTime object, but I'm getting an exception, I'm following this guide https://mkyong.com/java8/java-8-how-to-convert-string-to-localdate/, but unfortunately it doesn't have and example like the date I have below, can someone please give me a hand here? I would really appreciate :)

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEEE MMM d hh:mm:ss zzz yyyy",   Locale.US);
String date = "Wed Nov 18 00:00:00 COT 2020";
LocalDateTime localDateTime = LocalDateTime.parse(date, formatter);
System.out.println(localDateTime);
System.out.println(formatter.format(localDateTime));

I am getting:

java.time.format.DateTimeParseException: Text 'Wed Nov 18 00:00:00 COT 2020' could not be parsed at index 0

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
BugsForBreakfast
  • 712
  • 10
  • 30
  • @user16632363 edited question, still not working after removing the 5 before the date – BugsForBreakfast Nov 19 '21 at 00:55
  • 1
    Please give a more detailed problem description than "not working". – khelwood Nov 19 '21 at 00:57
  • @khelwood java.time.format.DateTimeParseException: Text 'Wed Nov 18 00:00:00 COT 2020' could not be parsed at index 0 – BugsForBreakfast Nov 19 '21 at 01:00
  • 1
    What does the Javadoc of DateTimeFormatter say about the number of pattern letters? – Sotirios Delimanolis Nov 19 '21 at 01:06
  • 1
    If you have `DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss zzz yyyy", Locale.US );` then you can parse it. But LocalDateTime does not contain TimeZone – Scary Wombat Nov 19 '21 at 01:06
  • 1
    Tip: Such localized strings should be generated only for presentation to the user. So you should not need to parse such values. In particular, you are using the 2-4 character pseudo-zones that are not unique! So parsing can only guess at which of multiple time zones you intend. Instead, for serializing date-time values textually, use only the standard [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) formats. – Basil Bourque Nov 19 '21 at 03:12

2 Answers2

3

If you want round trip parsing/formatting with Zones try

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss zzz yyyy",   Locale.US);
    String date = "Wed Nov 18 00:00:00 COT 2020";
    ZonedDateTime localDateTime = ZonedDateTime.parse(date, formatter);
    System.out.println(localDateTime);
    System.out.println(formatter.format(localDateTime));
Scary Wombat
  • 44,617
  • 6
  • 35
  • 64
2

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():

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161