How to parse custom multiple Date formats in Java
Asked Answered
K

1

5

I want to parse custom multiple Date formats in Java. Here is my code

Scenario 1: Order of patterns:

  • yyMMdd'h'HH
  • yyMMdd

DateTimeFormatter formatter = new DateTimeFormatterBuilder() .appendOptional(DateTimeFormatter.ofPattern("yyMMdd'h'HH")) .appendOptional(DateTimeFormatter.ofPattern("yyMMdd")).toFormatter();

Works:

String dateString1 = "201028h05";

LocalDateTime date1 = LocalDateTime.parse(dateString1, formatter);

Doesn't works:

String dateString2 = "201028";

LocalDateTime date1 = LocalDateTime.parse(dateString2, formatter);

Scenario 2: Order of patterns:

  • yyMMdd
  • yyMMdd'h'HH

DateTimeFormatter formatter = new DateTimeFormatterBuilder() .appendOptional(DateTimeFormatter.ofPattern("yyMMdd")).toFormatter(); .appendOptional(DateTimeFormatter.ofPattern("yyMMdd'h'HH"))

Doesn't Work:

  String dateString1 = "201028h05";
    
    LocalDateTime date1 = LocalDateTime.parse(dateString1, formatter);
    

Works:

String dateString2 = "201028";

LocalDateTime date1 = LocalDateTime.parse(dateString2, formatter);

How to make it work for both of the date patterns irrespective of any input pattern order. I don't want to use any external dependency for this.

Kenya answered 30/12, 2020 at 8:6 Comment(6)
What if you swap the order in which you insert the patterns? From most generic to more specific (instead of more specific to most generic)?Barcus
It works if I swap the order. But input value should be matched with the first pattern, if it doesn't match, it throws error.Kenya
Not sure I understand, but the second dateString1 does not match the pattern yyMMdd'h'HH, since it is missing the whole 'h'HH component. You would need to add something of the sort h00 to the second dateString1 for it to be captured by the first pattern.Barcus
@Barcus Update the question with scenariosKenya
What result do you want or expect when there is no hour of day in the string?Alliber
Scenario 1 should work for both after you add default time (see answer from Matt below). With multiple optional patterns, my observation is I have to put the most detailed patterns first. For example: one pattern is "YYYYmm" needs to go before "YYYY" for "2024" to be parsed, otherwise it would complain about the extra "mm" when seeing something like "202412".Defalcation
O
11

You can use [] to define the optional parts within a pattern. Additionally you need to set defaults to not get an exception when no time is supplied.

DateTimeFormatter formatter = new DateTimeFormatterBuilder()
        .appendPattern("yyMMdd['h'HH]")
        .parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
        .parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
        .parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0)
        .toFormatter();

String dateString1 = "201028h05";
LocalDateTime date1 = LocalDateTime.parse(dateString1, formatter);
System.out.println(date1);

String dateString2 = "201028";
LocalDateTime date2 = LocalDateTime.parse(dateString2, formatter);
System.out.println(date2);

Output:

2020-10-28T05:00
2020-10-28T00:00
Orchardman answered 30/12, 2020 at 8:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.