how to convert a String date value of pattern dd-MMM-yy to Date object of Pattern dd/MM/yyyy in java

Viewed 1327

I have

String dateAsString = "15-May-84";

and I want to convert it as

Date date = 15/05/1984;

first try

new SimpleDateFormat("dd/MM/yyyy").format(new Date(dateAsString )), "dd/MM/yyyy")

second try

LocalDate.parse(dateAsString , DateTimeFormatter.ofPattern("dd/MM/uuuu")));

I tried many ways with SimpleDateFormat and LocalDate but it's always returning 15/05/0084.

can anyone help here please

4 Answers

First of all, it's not good to use year as two digits as a string, Why?

Explanation

to parse your date, it is easy, you can use:

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MMM-yy")
        .withLocale(Locale.US);

LocalDate ld = LocalDate.parse("15-May-84", formatter);

But

This will return 2084-05-15, which I think you are not looking to this, but you look to 1984-05-15.

Quick Fix

So to solve this, you can use use minusYears(100):

LocalDate ld = LocalDate.parse("15-May-84", formatter).minusYears(100);

But

Which can be a problem to other years like 15-May-20 which will return 1920-05-15.

For that I don't advice at all to use two digits in your year as a string.

Unless

unless you have another confirmation that your date is between 1900 and 1999, or between 2000 and 2999. in this case you can create a (safe) custom parser!


Important

Don't use the legacy Date library, instead use only the modern java.time API

java.time

I am showing you the modern way using LocalDate and DateTimeFormatter beacase java.time, the modern Java date and time API, is so nice to work with. The classes Date and SimpleDateFormat are not only poorly designed, they are also long outdated, so I don’t recommend trying those.

I am assuming that you want a date that is today or in the past, not in the future and less than 100 years ago.

    LocalDate today = LocalDate.now(ZoneId.of("Asia/Kolkata"));
    int thisYear = today.getYear();

    String dateAsString = "15-May-84";

    DateTimeFormatter dateFormatter = new DateTimeFormatterBuilder()
            .appendPattern("d-MMM-")
            .appendValueReduced(ChronoField.YEAR_OF_ERA, 2, 2, thisYear - 99)
            .toFormatter(Locale.ENGLISH);
    LocalDate date = LocalDate.parse(dateAsString, dateFormatter);
    if (date.isAfter(today)) {
        // Go 100 years back
        dateFormatter = new DateTimeFormatterBuilder()
                .appendPattern("d-MMM-")
                .appendValueReduced(ChronoField.YEAR_OF_ERA, 2, 2, thisYear - 100)
                .toFormatter(Locale.ENGLISH);
        date = LocalDate.parse(dateAsString, dateFormatter);
    }

    System.out.println(date);

Output:

1984-05-15

If you want a different base year, just supply a different base year. And if you can, do a stricter range check so you are quite sure that you get a correct date for dates near the ends of the valid range. For example, if parsing the birth date of a living person aged between 18 and 80, make that your limits.

What went wrong in your code?

  1. When using a formatter for parsing your string, you need to supply a format pattern string that specifies the format to be parsed, not the desired result format. When parsing a string with hyphens, you need hyphens in the format pattern string, not slashes. And BTW, you cannot have a LocalDate or Date in your desired a format. Neither a LocalDate nor a Date has a format. You can have a format only in a String.
  2. Using yyyy with SimpleDateFormat specifies that the date string contains a full year, so year 84 is taken as year 84 CE, 1936 years ago. uuuu with DateTimeFormatter is even stricter, it specifies that the year must be at least 4 digits, so cannot parse 84 at all.

Link

Oracle tutorial: Date Time explaining how to use java.time.

You can use below code to work with different date formats

    String dateAsString = "15-May-84";
    SimpleDateFormat format = new SimpleDateFormat("dd-MMMM-yy");
    SimpleDateFormat newFormat = new SimpleDateFormat("dd/MM/yyyy");
    Date date = format.parse(dateAsString);
    String newDateString = newFormat.format(date);
    System.out.println(newDateString);

You can use SimpleDateFormat#parse:

Date date = new SimpleDateFormat("dd/MM/yyyy").parse("26/06/2020");
Related