2

I am trying to parse a simple string [08/May/2020:09:14:05 +0000] to LocalDateTime using DateTimeFormatter and LocalDateTime but it seems that it does not work for some reasons. I have tried different changes to the format like DD, hh, X, x, or Z but it doesn't work.

Here is the code:

String log = "[08/May/2020:09:14:05 +0000]";
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("[d/MMM/yyyy:HH:mm:ss x]");
LocalDateTime odt = LocalDateTime.parse(log, fmt);
System.out.println(odt);

Any guess?

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
Ihsan Haikal
  • 1,085
  • 4
  • 16
  • 42
  • 1
    `[...]` has special meaning in a date format pattern (means "optional"), so you need to quote them: `"'['d/MMM/yyyy:HH:mm:ss x']'"` – Andreas May 13 '20 at 14:44
  • @Andreas it still didn't work – Ihsan Haikal May 13 '20 at 14:45
  • When using text fields, it's always best to specify the language, so it won't try to use e.g. German month names. Also, the year should use `uuuu`: `ofPattern("'['d/MMM/uuuu:HH:mm:ss x']'", Locale.US)` – Andreas May 13 '20 at 14:47
  • 2
    Since the string includes a time zone offset, are you sure you want to parse to `LocalDateTime`, and not `OffsetDateTime`? – Andreas May 13 '20 at 14:49
  • @Andreas still does not work somehow, I have tried with OffsetDateTime as well but no luck – Ihsan Haikal May 13 '20 at 14:50
  • 2
    Use `DateTimeFormatter.ofPattern("'['dd/MMM/uuuu:HH:mm:ss xx']'", Locale.US)` – Andreas May 13 '20 at 14:53

2 Answers2

2

All credit goes to Andreas. His suggestion in the comments is good enough to be posted as an answer.

    String log = "[08/May/2020:09:14:05 +0000]";
    DateTimeFormatter fmt = DateTimeFormatter.ofPattern("'['dd/MMM/uuuu:HH:mm:ss xx']'", Locale.US);
    LocalDateTime odt = LocalDateTime.parse(log, fmt);
    System.out.println(odt);

Output is:

2020-05-08T09:14:05

In the format pattern string the square brackets [ and ] are (usually) used to enclose optional parts of the format. Since you want to specify that literal square brackets are in the date-time string, enclose them in apostrophes in the format pattern string. This cancels the meaning that the brackets have otherwise.

Also use xx for UTC offset with hours and minutes without colon such as +0000.

Finally always specify locale when the string includes locale sensitive parts such as a month abbreviation. In this case I think that any English-speaking locale will work, including Locale.ENGLISH, Locale.ROOT, Locale.UK, Locale.US and many others.

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

Get rid of the square brackets. And add another x to the timezone format.

log = log.replaceAll("\\[", "");
log = log.replaceAll("]", "");
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("[d/MMM/yyyy:HH:mm:ss xx]");

You can add the brackets back in with

System.out.println("[" + odt + "]");

Also, you may want to add another 'd' to the day of the month.

DateTimeFormatter fmt = DateTimeFormatter.ofPattern("[dd/MMM/yyyy:HH:mm:ss xx]");
tinymothbrain
  • 412
  • 2
  • 6