-1
String dateFormat = "20211109";
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
Date  strtDt = sdf.parse(dateFormat);
String strt = sdf.format(strtDt);

I am getting an error Unparseable date: "20211109"

How to convert date into given format and parse?

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
Aaa
  • 31
  • 1
  • 5
  • 1
    I recommend you don’t use `SimpleDateFormat` and `Date`. Those classes are poorly designed and long outdated, the former in particular notoriously troublesome. Instead use `LocalDate` and `DateTimeFormatter`, both from [java.time, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/). – Ole V.V. Nov 09 '21 at 18:58

2 Answers2

6

You are using the wrong input given the format of SimpleDateFormat, which should be of form 11/09/2021 (note that month comes before day):

String dateFormat = "11/09/2021";
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
Date  strtDt = sdf.parse(dateFormat);
String strt = sdf.format(strtDt);

Otherwise, you can change the date pattern when constructing the SimpleDateFormat:

String dateFormat = "20211109";
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
Date  strtDt = sdf.parse(dateFormat);
String strt = sdf.format(strtDt);

EDIT

You can switch between formatter according to your input formatted string using a regular expression pattern matching:

Pattern pattern = Pattern.compile("^\\d{8}$");
SimpleDateFormat sdf;
if (pattern.matcher(input).matches()) {
    sdf = new SimpleDateFormat("yyyyMMdd");
} else {
    sdf = new SimpleDateFormat("MM/dd/yyyy");
}
Date  strtDt = sdf.parse(input);
String strt = sdf.format(strtDt);

You can also catch the ParseException to attempt another format parsing but I wouldn't recommend using exceptions for your program flow.

As @Ole V.V. suggested in his comment, you shouldn't be using the java.text.SimplateDateFormat and the java.util.Date classes for date types manipulation and parsing as those are outdated and may cause a lot of trouble along the way.

If you are on JDK 1.8 and onward, you should use the new Date Time APIs introduced in JSR 310:

String dateFormat = "20211109";
DateTimeFormatter formatter = DateTimeFormatter.BASIC_ISO_DATE;
// Same as `DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");`
LocalDateTime  strtDt = formatter.parse(dateFormat, LocalDateTime::from);
String strt = formatter.format(strtDt);
tmarwen
  • 15,750
  • 5
  • 43
  • 62
  • Was about to edit it, thanks @Pshemo for the extra fix :) – tmarwen Nov 09 '21 at 17:54
  • can we change the date format? if I am giving input yyyyMMdd then can we convert into MM/dd/yyyy? – Aaa Nov 09 '21 at 18:25
  • If you have a fixed input format, why would you want to change the pattern dynamically? Are you looking to support multiple input formats? – tmarwen Nov 09 '21 at 18:41
  • yes i needed to chech the format of date and if date format is yyyyMMdd then convert into MM/dd/yyyy – Aaa Nov 09 '21 at 18:51
  • You should then pair date formatting with a regular expression validation even though based on my experience, it is always more safe to allow only a pre-defined format. I am updating the answer. – tmarwen Nov 09 '21 at 18:56
  • Not directly incorrect. However, no one should use `SimpleDateFormat` in 2021, so helping people how to do it any way IMHO is really doing them a mis-favour (if that’s a word; possibly *ill turn* is better). – Ole V.V. Nov 09 '21 at 18:59
  • @OleV.V. I absolutely agree and I have in any way recommended to do it. Contexts may vary and the main OP author may be constrained to use a particular API. Nevertheless I added an extra entry for the newer `Date Time` APIs. – tmarwen Nov 09 '21 at 19:15
3

java.time

I strongly recommend that you use java.time, the modern Java date and time API, for your date work.

It generally takes two formatters for converting a string date in one format to a string in another format: one for describing the format you got, and one for the required format. In this case the former is built in. For your required result define a formatter statically:

private static final DateTimeFormatter DATE_FORMATTER
        = DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM)
                .withLocale(Locale.forLanguageTag("es-PA"));

The do:

    String dateFormat = "20211109";
    LocalDate start = LocalDate.parse(dateFormat, DateTimeFormatter.BASIC_ISO_DATE);
    String string = start.format(DATE_FORMATTER);
    System.out.println(string);

Output:

11/09/2021

For formatting I took the built-in medium date format for Panama since this is one of the locales where the format fits what you asked for. You should of course use your users’ locale, not the one of Panama, for an output format that they will recognize as their own. In this way we are saving ourselves the trouble of composing a format pattern string, and at the same time the code lends itself excellently to internationalization.

You shouldn’t want to convert from one string format to another

If you are asking how to convert a date from one string format to another, you are really asking the wrong question. In all but the smallest throw-away programs, we should not handle dates as strings, but always store them in LocalDate objects. When we take string input, we parse. Only when we need to give string output, we format back.

Using a format pattern

If for one reason or another your users are not happy with Java’s localized format, and you need more control over the output format, you may use a format pattern as you tried in your question:

private static final DateTimeFormatter DATE_FORMATTER
        = DateTimeFormatter.ofPattern("MM/dd/yyyy", Locale.ROOT);

Links

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161