-4

I am trying to parse a date into an appropriate format, but I keep getting the error

Unparseable date

Can anyone tell me what the mistake is?

try {
    System.out.println(new SimpleDateFormat("d-MMM-Y").parse("05-03-2018").toString());
} catch (ParseException e) {
    e.printStackTrace();
}

I want the date to have this format:

05-Mar-18

Neuron
  • 5,141
  • 5
  • 38
  • 59
Mayank Aggarwal
  • 169
  • 1
  • 15
  • How do you want the date should look? Can you mention your expected output sample date? – Safeer Ansari Mar 09 '18 at 06:00
  • 1
    Does 05-03-2018 match the pattern d-MMM-Y in your eyes? On what basis dd you choose this pattern? Don't try random things. Read the javadoc. – JB Nizet Mar 09 '18 at 06:00
  • MMM stands for AUG (August), you are having 03 (for March), for this change MMM to MM, also date must also set to dd instead of d. – ashishdhiman2007 Mar 09 '18 at 06:00
  • 1
    @SafeerAnsari Added the expected output – Mayank Aggarwal Mar 09 '18 at 06:08
  • I recommend you avoid the `SimpleDateFormat` class. It is not only long outdated, it is also notoriously troublesome. Today we have so much better in [`java.time`, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/). You will want to look into the classes `LocalDate` and `DateTimeFormatter`. And you will want two formatters, one for parsing and one for formatting. – Ole V.V. Mar 09 '18 at 07:58
  • 1
    Possible duplicate of [Changing String date format](https://stackoverflow.com/questions/34846358/changing-string-date-format). I recommend [my own answer here](https://stackoverflow.com/a/48299652/5772882), only in your case use `LocalDate` instead of `LocalDateTime`. This question has been asked and answered many times, so feel free to search for other answers too. – Ole V.V. Mar 09 '18 at 08:10

2 Answers2

2

Since you want to change the format, first read and parse the date (from String) of your own format in a Date type object. Then use that date object by formatting it into a new (desired) format using a SimpleDateFormat.

The error in your code is with the MMM and Y. MMM is the month in string while your input is a numeric value. Plus the Y in your SimpleDateFormat is an invalid year. yy is what needs to be added.

So here is a code that would fix your problem.

SimpleDateFormat dateFormat = new SimpleDateFormat("d-MM-yyyy");
Date date = dateFormat.parse("05-03-2018");
dateFormat = new SimpleDateFormat("dd-MMM-yy");
System.out.println(dateFormat.format(date));

I hope this is what you're looking for.

shind
  • 115
  • 4
Safeer Ansari
  • 772
  • 4
  • 13
1

There are some concepts about dates you should be aware of.

There's a difference between a date and a text that represents a date.

Example: today's date is March 9th 2018. That date is just a concept, an idea of "a specific point in our calendar system".

The same date, though, can be represented in many formats. It can be "graphical", in the form of a circle around a number in a piece of paper with lots of other numbers in some specific order, or it can be in plain text, such as:

  • 09/03/2018 (day/month/year)
  • 03/09/2018 (monty/day/year)
  • 2018-03-09 (ISO8601 format)
  • March, 9th 2018
  • 9 de março de 2018 (in Portuguese)
  • 2018年3月5日 (in Japanese)
  • and so on...

Note that the text representations are different, but all of them represent the same date (the same value).

With that in mind, let's see how Java works with these concepts.

  • a text is represented by a String. This class contains a sequence of characters, nothing more. These characters can represent anything; in this case, it's a date
  • a date was initially represented by java.util.Date, and then by java.util.Calendar, but those classes are full of problems and you should avoid them if possible. Today we have a better API for that.

With the java.time API (or the respective backport for versions lower than 8), you have easier and more reliable tools to deal with dates.

In your case, you have a String (a text representing a date) and you want to convert it to another format. You must do it in 2 steps:

  1. convert the String to some date-type (transform the text to numerical day/month/year values) - that's called parsing
  2. convert this date-type value to some format (transform the numerical values to text in a specific format) - that's called formatting

For step 1, you can use a LocalDate, a type that represents a date (day, month and year, without hours and without timezone), because that's what your input is:

String input = "05-03-2018";
DateTimeFormatter inputParser = DateTimeFormatter.ofPattern("dd-MM-yyyy");
// parse the input
LocalDate date = LocalDate.parse(input, inputParser);

That's more reliable than SimpleDateFormat because it solves lots of strange bugs and problems of the old API.

Now that we have our LocalDate object, we can do step 2:

// convert to another format
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MMM-yy", Locale.ENGLISH);
String output = date.format(formatter);

Note that I used a java.util.Locale. That's because the output you want has a month name in English, and if you don't specify a locale, it'll use the JVM's default (and who guarantees it'll always be English? it's better to tell the API which language you're using instead of relying on the default configs, because those can be changed anytime, even by other applications running in the same JVM).

And how do I know which letters must be used in DateTimeFormatter? Well, I've just read the javadoc. Many developers ignore the documentation, but we must create the habit to check it, specially the javadoc, that tells you things like the difference between uppercase Y and lowercase y in SimpleDateFormat.

shind
  • 115
  • 4