2

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);



Elia123456
  • 43
  • 4
  • 2
    Your solution will not work. It would first remove the "st" in "August" for example. – Sweeper Apr 20 '21 at 05:21
  • 1
    [This](https://stackoverflow.com/q/42486011/10819573) and [this](https://stackoverflow.com/q/4011075/10819573) should solve your problem. – Arvind Kumar Avinash Apr 20 '21 at 05:29
  • @Sweeper ohh snap I'm an idiot lol thanks for pointing that out – Elia123456 Apr 20 '21 at 05:37
  • You will not want to use `SimpleDateFormat` and `Date`. Those classes are poorly designed and long outdated, the former in particular notoriously troublesome. Use `LocalDateTime` for at date with time of day, and stick to `DateTimeFormatter` (both are from [java.time, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/)). – Ole V.V. Apr 20 '21 at 06:23
  • user15793316 has removed `java.time` from this question as well as many questions without understanding that `DateTimeFormatter` and `LocalDate` belong to `java.time`. @Sweeper - What's your opinion? – Arvind Kumar Avinash May 15 '21 at 00:26
  • @ArvindKumarAvinash looking at the revision history, OP did not specifically ask for a java.time solution initially. By the logic of the linked meta post in the editor’s edit summary, the tag indeed should be deleted, as well as (arguably) simpledateformat and datetimeformatter. The java and datetime tags should be kept as those are the things that OP is specifically asking about. – Sweeper May 15 '21 at 00:37
  • @Sweeper - Interesting! I thought that `DateTimeFormatter` and `LocalDate` (which have been in the question since the beginning) belong to `java.time` and therefore `java.time` was the correct tag for it. Thanks for your response. – Arvind Kumar Avinash May 15 '21 at 09:21

2 Answers2

5

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);
Sweeper
  • 213,210
  • 22
  • 193
  • 313
1

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);
Naetmul
  • 14,544
  • 8
  • 57
  • 81
  • DateTimeformatter returned this error: Exception in thread "main" java.time.format.DateTimeParseException: Text 'April 5th 2021 12:30pm' could not be parsed at index 20 SimpleDateFormatter returned: Exception in thread "main" java.text.ParseException: Unparseable date: "April 5th 2021 12:30pm" – Elia123456 Apr 20 '21 at 05:20
  • @Elia123456 Updated the answer – Naetmul Apr 20 '21 at 05:41
  • Upvoted for `parseCaseInsensitive()` for lower-case am and pm. – Ole V.V. Apr 20 '21 at 06:25