fork download
  1. import java.time.format.DateTimeFormatter;
  2. import java.time.format.DateTimeFormatterBuilder;
  3. import java.time.format.ResolverStyle;
  4. import java.time.temporal.ChronoField;
  5. import java.time.temporal.TemporalAccessor;
  6. import java.time.ZoneOffset;
  7. import java.time.LocalDate;
  8. import java.time.LocalDateTime;
  9. import java.time.ZonedDateTime;
  10. import java.time.OffsetDateTime;
  11.  
  12. class Ideone
  13. {
  14. public static void main(String[] args) {
  15. try {
  16. // Define the formatter with year as the first component, followed by month and day
  17. DateTimeFormatterBuilder builder = new DateTimeFormatterBuilder()
  18. .appendPattern("yyyyMMdd"); // Year, Month, Day are now the base mandatory components
  19.  
  20. // Make subsequent components optional
  21. builder.optionalStart().appendPattern("HH").appendPattern("mm");
  22. builder.optionalEnd(); // End of HHmm
  23.  
  24. // Set default values for missing components to ensure successful parsing
  25. // and to get a consistent result (e.g., start of day/month/year).
  26. // Defaults for YEAR, MONTH, DAY are not strictly needed here since they are in the base pattern.
  27. // However, if the base pattern itself could be optional (e.g., just "yyyy" then "MM" optional),
  28. // these defaults would be critical.
  29. builder.parseDefaulting(ChronoField.HOUR_OF_DAY, 0);
  30. builder.parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0);
  31. builder.parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0);
  32. builder.parseDefaulting(ChronoField.NANO_OF_SECOND, 0); // Sets milliseconds to 0
  33. builder.parseDefaulting(ChronoField.OFFSET_SECONDS, ZoneOffset.UTC.getTotalSeconds()); // Default to UTC offset
  34.  
  35. DateTimeFormatter formatter = builder
  36. .toFormatter()
  37. .withResolverStyle(ResolverStyle.LENIENT); // Lenient for more forgiving parsing
  38.  
  39. DateTimeFormatter formatterWithOffset = builder
  40. .toFormatter()
  41. .withResolverStyle(ResolverStyle.LENIENT);
  42.  
  43. // --- Test cases ---
  44. System.out.println("Parsing '20230101' (yyyyMMdd): " + formatter.parseBest("20230101", ZonedDateTime::from, LocalDateTime::from, LocalDate::from));
  45. System.out.println("Parsing '20230115' (yyyyMMdd): " + formatter.parseBest("20230115", ZonedDateTime::from, LocalDateTime::from, LocalDate::from));
  46. System.out.println("Parsing '202301151030' (yyyyMMddHHmm): " + formatter.parseBest("202301151030", ZonedDateTime::from, LocalDateTime::from, LocalDate::from));
  47. System.out.println("Parsing '20230115103045' (yyyyMMddHHmmss): " + formatter.parseBest("20230115103045", ZonedDateTime::from, LocalDateTime::from, LocalDate::from));
  48. System.out.println("Parsing '20230115103045123' (yyyyMMddHHmmssSSS): " + formatter.parseBest("20230115103045123", ZonedDateTime::from, LocalDateTime::from, LocalDate::from));
  49.  
  50. System.out.println("Parsing '20230115103045123Z' (yyyyMMddHHmmssSSSZ): " + formatterWithOffset.parseBest("20230115103045123Z", ZonedDateTime::from, OffsetDateTime::from, LocalDateTime::from, LocalDate::from));
  51. System.out.println("Parsing '20230115103045123+0500' (yyyyMMddHHmmssSSS+HHMM): " + formatterWithOffset.parseBest("20230115103045123+0500", ZonedDateTime::from, OffsetDateTime::from, LocalDateTime::from, LocalDate::from));
  52. System.out.println("Parsing '20230115103045123-08' (yyyyMMddHHmmssSSS-HH): " + formatterWithOffset.parseBest("20230115103045123-08", ZonedDateTime::from, OffsetDateTime::from, LocalDateTime::from, LocalDate::from));
  53. } catch (Exception e) {
  54. System.out.println(e);
  55. }
  56. }
  57. }
Success #stdin #stdout 0.16s 56688KB
stdin
Standard input is empty
stdout
Parsing '20230101' (yyyyMMdd): 2023-01-01T00:00Z
Parsing '20230115' (yyyyMMdd): 2023-01-15T00:00Z
java.time.format.DateTimeParseException: Text '202301151030' could not be parsed at index 0