Home > Mobile >  String to date format and vice versa
String to date format and vice versa

Time:11-10

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?

CodePudding user response:

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

CodePudding user response:

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

  • Related