Formatting string to date in java

Viewed 142

I want to compare WebElements dates to validate if the sorting is correct. However, the values of the dates are for example as follows: "April 5th 2021 12:30pm", "October 22nd 2018 09:18am", "February 1st 2015 11:36pm",

I have tried the below code, but it's returning 1970 as the date and an error for the cases where the day is 2 digits:


DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("MMMM d yyyy HH:mma", Locale.US);
LocalDate date = LocalDate.parse(dt, dateFormatter);

// or

Date sdf = new SimpleDateFormat("MMMM d u hh:mma").parse(dt);



2 Answers

You can use a DateTimeFormatterBuilder to create a DateTimeFormatter that can parse days-of-month that have the "st", "nd", "rd" and "th" suffixes, and also lowercase AMPM.

// first create a map containing mapping the days of month to the suffixes
HashMap<Long, String> map = new HashMap<>();
for (long i = 1 ; i <= 31 ; i++) {
  if (i == 1 || i == 21 || i == 31) {
    map.put(i, i + "st");
  } else if (i == 2 || i == 22){
    map.put(i, i + "nd");
  } else if (i == 3 || i == 23) {
    map.put(i, i + "rd");
  } else {
    map.put(i, i + "th");
  }
}

DateTimeFormatter dateFormatter = new DateTimeFormatterBuilder()
    .appendPattern("MMMM ")
    .appendText(ChronoField.DAY_OF_MONTH, map) // here we use the map
    .appendPattern(" yyyy HH:mm")
    .appendText(ChronoField.AMPM_OF_DAY, Map.of(0L, "am", 1L, "pm")) // here we handle the lowercase AM PM
    .toFormatter(Locale.US);

Usage:

LocalDateTime datetime = LocalDateTime.parse("April 5th 2021 12:30pm", dateFormatter);

The format pattern d only accepts a number and does not accept st, nd, rd, and th.

Use optional sections with [ and ]. Also, a should be used with hh, not HH.

OK. It seems that Locale.US only accepts "AM" and "PM" whereas Locale.UK only accepts "am" and "pm".

DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("MMMM d['st']['nd']['rd']['th'] yyyy hh:mma", Locale.UK);
LocalDate date = LocalDate.parse(dt, dateFormatter);

or

DateTimeFormatter dateFormatter = new DateTimeFormatterBuilder()
        .parseCaseInsensitive()
        .appendPattern("MMMM d['st']['nd']['rd']['th'] yyyy hh:mma")
        .toFormatter(Locale.US);
LocalDate date = LocalDate.parse(dt, dateFormatter);
Related