Java DateTimeFormatter expression to parse "Wed Jun 03 12:00:00 PM GMT 2020"

62 views Asked by At

I am using an application written in Java, that uses LocalDate.parse with a DateTimeFormatter:

LocalDate.parse("Wed Jun 03 12:00:00 PM GMT 2020", DateTimeFormatter.ofPattern("EEE MMM dd hh:mm:ss a zzz yyyy"));

I can only provide the format string (I cannot modify the source code). I need it to successfully parse a somewhat crazy date format that looks like this:

Wed Jun 03 12:00:00 PM GMT 2020

The closest format I've gotten to is:

EEE MMM dd hh:mm:ss a zzz yyyy

but this bombs out with

Exception java.time.format.DateTimeParseException: Text 'Wed Jun 03 12:00:00 PM GMT 2020' could not be parsed at index 20

If I remove the AM/PM in the date and format, all works fine. Any tweaks that will make this parse successfully?

1

There are 1 answers

3
Basil Bourque On

tl;dr

ZonedDateTime.parse( 
    "Wed Jun 03 12:00:00 PM GMT 2020" , 
    DateTimeFormatter
        .ofPattern( "EEE MMM dd HH:mm:ss a z uuuu" )
        .withLocale( Locale.US )
)
.toInstant()
.toString()

2020-06-03T12:00Z

ZonedDateTime, not LocalDate

LocalDate is the wrong class for your input. A LocalDate has only a date, no time-of-day, and no time zone.

You should be using ZonedDateTime class.

Specify locale for localization rules

Define a custom format matching your output using the DateTimeFormatter class.

Specify a Locale. Your input is localized in multiple ways: Name of day of week, name of month, and AM/PM. Choose a Locale that represents the localization choices seen in your inputs. I believe Locale.US might work.

String input = "Wed Jun 03 12:00:00 PM GMT 2020" ;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "EEE MMM dd HH:mm:ss a z uuuu" ).withLocale( Locale.US ) ;
ZonedDateTime zdt = ZonedDateTime.parse( input , f ) ;

zdt.toString() = 2020-06-03T12:00Z[GMT]

LocalDate

If you really want only the date portion, and wish to discard the time-of-day and offset/zone, then parse as a LocalDate while using the same correct formatting pattern.

LocalDate ld = 
    LocalDate.parse( 
        "Wed Jun 03 12:00:00 PM GMT 2020" , 
        DateTimeFormatter
            .ofPattern( "EEE MMM dd HH:mm:ss a z uuuu" )
            .withLocale( Locale.US )
    );

See this code run at Ideone.com. Be aware that the date extracted is the date as seen in the parsed time zone.

ld.toString() = 2020-06-03

ISO 8601

The ideal solution is educate the publisher of your data about the ISO 8601 standard for communicating date-time values unambiguously as text.

Your example input should have been sent as: 2020-06-03T12:00Z

The Z on the end is an abbreviation of +00:00, pronounced “Zulu”, and means an offset of zero hours-minutes-seconds ahead of the temporal meridian of UTC.