2

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

Youcef LAIDANI
  • 55,661
  • 15
  • 90
  • 140
  • 1
    can you show us what you tried please? – Youcef LAIDANI Mar 26 '20 at 10:25
  • tried below codes: LocalDate.parse("15-May-84", DateTimeFormatter.ofPattern("dd/MM/uuuu"))) and new SimpleDateFormat("dd/MM/yyyy").format(new Date(15-May-84)), "dd/MM/yyyy") – LearningCode Mar 26 '20 at 10:27
  • edit your question and put the code – Youcef LAIDANI Mar 26 '20 at 10:28
  • 1
    In short, use a LocalDate class and two DateFormatter instances for parsing the old date and formatting the new one. Also, this is a very googleable question that probably has numerous answers on SO. Next time, please search bit harder. – Jilles van Gurp Mar 26 '20 at 10:29
  • 1
    I recommend you don’t use `SimpleDateFormat` and `Date`. Those classes are poorly designed and long outdated, the former in particular notoriously troublesome. `LocalDate` and `DateTimeFormatter` from [java.time, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/) are the classes to use. – Ole V.V. Mar 26 '20 at 10:49
  • Thnaks Jilles, bit it's returning 15/05/0094 while passing 15-May-94 with the edited code – LearningCode Mar 26 '20 at 11:04
  • Does this answer your question? [Parsing string to local date doesn't use desired century](https://stackoverflow.com/questions/29490893/parsing-string-to-local-date-doesnt-use-desired-century) – Ole V.V. Mar 26 '20 at 18:53

4 Answers4

2

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

Youcef LAIDANI
  • 55,661
  • 15
  • 90
  • 140
  • Instead of using minusYears, it’s better to build a DateFormatter with an explicit base year, using [appendValueReduced](https://docs.oracle.com/en/java/javase/14/docs/api/java.base/java/time/format/DateTimeFormatterBuilder.html#appendValueReduced%28java.time.temporal.TemporalField,int,int,int%29). – VGR Mar 26 '20 at 14:28
1

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.

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

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

You can use SimpleDateFormat#parse:

Date date = new SimpleDateFormat("dd/MM/yyyy").parse("26/06/2020");
htmoia
  • 429
  • 4
  • 9
  • 1
    This does not answer the question. It does not even make use of the `dateAsString` value. – VGR Mar 26 '20 at 14:23