-1

I have input date like April 17th, 2024. Date was constructed by google speech to text service.

To format this date into different format I would use next code:

        String input = "April 17th, 2024";
        DateTimeFormatter f = DateTimeFormatter.ofPattern( "MMM d, uuuu" )
                .withLocale( Locale.US );
        ZonedDateTime zdt = ZonedDateTime.parse( input , f );

        LocalDate ld = zdt.toLocalDate();
        DateTimeFormatter fLocalDate = DateTimeFormatter.ofPattern( "dd/MM/uuuu" );
        String output = ld.format( fLocalDate);
        System.out.println(output);

...the issue is that input date should be April 17, 2024 or pattern have to be improved.

Very strict solution is to cut out letters after number.

I would prefer to avoid of adding additional logic and improve date pattern for input data. Exactly with this step I need help (I can't find correct solution in java doc).

So I hope to get formatter correction or confirmation, that java doesn't support standards where date can be 17th, 3rd and so on.

Sergii
  • 7,044
  • 14
  • 58
  • 116
  • 1
    It will really be easier for you to just run four `replace` calls for your input string, removing "st", "nd", "rd", "th". For safety you can include comma. – NRUB Nov 27 '20 at 18:00
  • I know that the troublesome and outdated `SimpleDateFormat` was asked about in the linked original question, but [my answer here](https://stackoverflow.com/a/57116982/5772882) uses `DateTimeFormatter` and java.time, the modern Java date and time API. – Ole V.V. Nov 27 '20 at 19:10
  • A couple of other issues: (1) You need `MMMM` for full month name. `MMM` is for month abbreviation like `Apr`. (2) You can’t parse into a `ZonedDateTime` when the string neither contains time of day nor time zone. Parse into a `LocalDate`. – Ole V.V. Nov 27 '20 at 19:28
  • Thanks to all. I think the question is duplicate, and best answer is [here](https://stackoverflow.com/a/4722379/5728095) – Sergii Nov 28 '20 at 16:54
  • 2
    Thanks for reporting back. I beg to differ. You were already using java.time, the modern Java date and time API. You are linking to an answer that uses the notoriously troublesome and long outdated `SimpleDateFormat` class and other poorly designed date-time classes. It’s a *huge* step backward. It could never be the best answer. – Ole V.V. Nov 30 '20 at 05:24

2 Answers2

2

it seems that java.time doesn't support ordinal numbers.

a "pattern solution" I can think of, would be one using optional sections (i.e characters between [ and ]): MMMM d['th']['st']['nd']['rd'], yyyy

for example:

jshell> var fmt = DateTimeFormatter.ofPattern("MMMM d['th']['st']['nd']['rd'], yyyy").withLocale(Locale.US)
fmt ==> Text(MonthOfYear)' 'Value(DayOfMonth)['th']['st'] ... earOfEra,4,19,EXCEEDS_PAD)

jshell> LocalDate.parse("April 17th, 2024", fmt)
$63 ==> 2024-04-17

jshell> LocalDate.parse("April 1st, 2024", fmt)
$64 ==> 2024-04-01

jshell> LocalDate.parse("April 3rd, 2024", fmt)
$65 ==> 2024-04-03

jshell> LocalDate.parse("April 4, 2024", fmt)
$66 ==> 2024-04-04

it will reject others characters:

jshell> LocalDate.parse("April 1fo, 2024", fmt)
|  Exception java.time.format.DateTimeParseException: Text 'April 1fo, 2024' could not be parsed at index 7
|        at DateTimeFormatter.parseResolved0 (DateTimeFormatter.java:2046)
|        at DateTimeFormatter.parse (DateTimeFormatter.java:1948)
|        at LocalDate.parse (LocalDate.java:428)
|        at (#68:1)

jshell> LocalDate.parse("April 1baar, 2024", fmt)
|  Exception java.time.format.DateTimeParseException: Text 'April 1baar, 2024' could not be parsed at index 7
|        at DateTimeFormatter.parseResolved0 (DateTimeFormatter.java:2046)
|        at DateTimeFormatter.parse (DateTimeFormatter.java:1948)
|        at LocalDate.parse (LocalDate.java:428)
|        at (#69:1)

but it will accept e.g. April 1th, 2024, even if is not strictly correct:

jshell> LocalDate.parse("April 1th, 2024", fmt)
$67 ==> 2024-04-01

and it will also accept January 3thstndrd, 2024. I don't know if could be a problem:

jshell> LocalDate.parse("January 3thstndrd, 2024", fmt)
$97 ==> 2024-01-03
MarcoLucidi
  • 2,007
  • 1
  • 5
  • 8
1

Java's date formatters/parsers don't support ordinal numbers.

It doesn't really matter what you prefer, you have to remove the ordinal suffix yourself, before invoking the parser.

It really isn't that bad, e.g.

ZonedDateTime zdt = ZonedDateTime.parse( input.replaceFirst("(?:st|nd|rd|th),", ",") , f );
Andreas
  • 154,647
  • 11
  • 152
  • 247
  • 1
    Not perfect. You need `MMMM` for full month name like `April`. You can’t parse into `ZonedDateTime` without time of day and time zone. Try `LocalDate.parse( input.replaceFirst("(?:st|nd|rd|th),", ",") , f )`. – Ole V.V. Nov 27 '20 at 19:32
  • 1
    @OleV.V. Since this answer is only about the removal of the ordinal suffix, and don't even show the date format pattern, why are you telling me? Say it in the question, or write an answer. – Andreas Nov 28 '20 at 00:55
  • 1
    Sorry, didn’t mean to annoy. I have commented under the question (and have closed it, as you can see). Still think my comment here may be helpful for readers of your answer, so letting it stand. – Ole V.V. Nov 28 '20 at 05:56