4

I am trying to convert a String to LocalDate using DateTimeFormatter, but I receive an exception:

java.time.format.DateTimeParseException: Text '2021-10-31' could not be parsed at index 5

My code is

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MMM-uuuu");
String text = "2021-10-31";
LocalDate date = LocalDate.parse(text, formatter);

I am trying to convert from input date 2021-10-31 to 31-Oct-2021.

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
Arooshi
  • 91
  • 5
  • 2
    How does “10” match the pattern of MMM? In fact, how does 2021 match “dd”? – MadProgrammer Nov 06 '21 at 22:58
  • 1
    It has been voted to close this question as not reproducible or caused by a typo. Doing so would be wrong. The problem asked about is trivially reproducible always and was not caused by a typo. On the contrary this question is about an error that is not uncommon (trying to use the desired output format for parsing the input), so it will be useful and valuable to keep this question around for future reference. – Ole V.V. Nov 07 '21 at 06:43
  • Related question, but about Scala: [Date Time formatting in scala error: "text could not be parsed at index 0"](https://stackoverflow.com/questions/69256650/date-time-formatting-in-scala-error-text-could-not-be-parsed-at-index-0) – Ole V.V. Nov 07 '21 at 06:44

2 Answers2

6

Whats wrong?

What Am I doing wrong in my code.

Your code specifies the pattern dd-MMM-uuuu, but you attempt to parse the text 2021-10-31 which does not fit this pattern at all.

The correct pattern for your string would be yyyy-MM-dd. See the documentation of the formatter for details.

In particular, watch the order of the days and months dd-MMM vs MM-dd. And the amount of months MMM. A string matching your current pattern would be 31-Oct-2021.


Change pattern

From the comments:

my input date is - 2021-10-31 need to covert into - 31-Oct-2021

You can easily change the pattern of the date by:

  1. Parsing the input date using the pattern yyyy-MM-dd
  2. and then format it back to string using the pattern dd-MMM-yyyy.

In code, that is:

DateTimeFormatter inputPattern = DateTimeFormatter.ofPattern("yyyy-MM-dd");
DateTimeFormatter outputPattern = DateTimeFormatter.ofPattern("dd-MMM-yyyy");

String input = "2021-10-31";
LocalDate date = LocalDate.parse(text, inputPattern);

String output = date.format(outputPattern);
Zabuzard
  • 25,064
  • 8
  • 58
  • 82
  • my input date is - 2021-10-31 need to covert into - 31-Oct-2021 – Arooshi Nov 06 '21 at 23:06
  • 1
    @Arooshi Parse the input date using the pattern `yyyy-MM-dd` and then format it back to string using the pattern `dd-MMM-yyyy`. – Zabuzard Nov 06 '21 at 23:08
  • Your code prints `31-10月-2021`. –  Nov 06 '21 at 23:16
  • @saka1029deleted You have to set the locale to english if you want to get english month names. In chinese, japanese, ... you will just get `日`, `月` and so on. – Zabuzard Nov 06 '21 at 23:17
  • @saka1029deleted Please read the documentation of `DateTimeFormatter` that I linked in my answer. There is `ofPattern(..., locale)`, `withLocale(locale)` and `localizedBy(locale)`, So for example `ofPattern("dd-MMM-yyyy", Locale.ENGLISH)`. – Zabuzard Nov 06 '21 at 23:21
4

You do not need to use a DateTimeFormatter to parse your input string

The modern Date-Time API is based on ISO 8601 and does not require using a DateTimeFormatter object explicitly as long as the Date-Time string conforms to the ISO 8601 standards. Note that your date string is already in ISO 8601 format.

You need a DateTimeFormatter just to format the LocalDate obtained by parsing the input string.

Demo:

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        LocalDate date = LocalDate.parse("2021-10-31");
        System.out.println(date);

        DateTimeFormatter dtfOutput = DateTimeFormatter.ofPattern("dd-MMM-uuuu", Locale.ENGLISH);
        System.out.println(date.format(dtfOutput));
    }
}

Output:

2021-10-31
31-Oct-2021

ONLINE DEMO

Make sure to use Locale when using a DateTimeFormatter. Check Never use SimpleDateFormat or DateTimeFormatter without a Locale to learn more about it.

Learn more about the modern Date-Time API* from Trail: Date Time.


* If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring. Note that Android 8.0 Oreo already provides support for java.time. Check this answer and this answer to learn how to use java.time API with JDBC.

Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110