-1

I've been struggling trying to migrate a String to Date parse from java.util.Date to java.time.LocalDate

For instance, I don't know what pattern the user's input String will have... but I do know the user's java.util.Locale, from which I currently get the pattern for the convertion using java.text.SimpleDateFormat#toLocalizedPattern

This works, using old java.util.Date

// "25/05/2022" , Locale es-ES
public Date stringToDate(String dateString, Locale locale) throws ParseException {
    DateFormat dtf = DateFormat.getDateInstance(DateFormat.SHORT, locale);
    String pattern = ((SimpleDateFormat) dtf).toLocalizedPattern(); // d/M/yy

    return dtf.parse(dateString); // 2022/05/25
}

This doesn't work, using directly java.time.LocalDate, It ends up with a java.time.format.DateTimeParseException

// "25/05/2022" , Locale es-ES
public LocalDate stringToLocalDate(String dateString, Locale locale) throws DateTimeParseException {
    DateFormat dtf = DateFormat.getDateInstance(DateFormat.SHORT, locale);
    String pattern = ((SimpleDateFormat) dtf).toLocalizedPattern(); // d/M/yy

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern, locale);

    return LocalDate.parse(dateString, formatter); 
// Exception in thread "main" java.time.format.DateTimeParseException: Text '25/05/2022' could not be parsed, unparsed text found at index 8
}

I know I could do the convertion like this, converting the old java.util.Date class to the new java.time.LocalDate class, But the goal is to stop relying on java.util.Date

LocalDate locDate = LocalDate.ofInstant(date.toInstant(), ZoneOffset.UTC);

What would the correct conversion to LocalDate look like since I don't know the pattern of the date?

The current problem with converting to Date this way is that if the user enters, for example, 13/05/2022, in MM/dd/yyyy format, Java converts it to 01/05/2023. I'd rather have a handled Exception in this scenario.

Eric Ramírez
  • 29
  • 1
  • 5
  • 3
    `2022` and `yy` do not match. You are right, of course, in abandoning the old and poorly designed classes and getting things to work with java.time and `LocalDate` and `DateTimeFormatter` from the modern API. This also means: get the localized pattern from [`DateTimeFormatterBuilder.getLocalizedDateTimePattern()`](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/format/DateTimeFormatterBuilder.html#getLocalizedDateTimePattern(java.time.format.FormatStyle,java.time.format.FormatStyle,java.time.chrono.Chronology,java.util.Locale)), not from `DateFormat`. – Ole V.V. May 21 '22 at 18:44
  • 1
    From your first method I get `Tue Nov 12 00:00:00 CET 2030`. I agree with you that it is wrong. :-) – Ole V.V. May 21 '22 at 18:51
  • [Sample code with handled exception.](https://ideone.com/KbLOOe) – Ole V.V. May 21 '22 at 19:04
  • 1
    @OleV.V. Thanks for you reply, but your solution keeps failing where old Date works properly... Same input string, same locale, `Date` properly converts it, `LocalDate` throws Exception... [Code output](https://i.imgur.com/HTzFCoY.jpg) – Eric Ramírez May 22 '22 at 02:58
  • Do we agree that Java’s short Spanish date format is `d/M/yy` and not `d/M/yyyy`? And that each of your methods should therefore be able to parse `25/05/22` and should refuse to parse `25/05/2022`? – Ole V.V. May 22 '22 at 06:41
  • 1
    I have tried your code with your sample date string of `25/05/2022`. And got surprised: the old `SimpleDateFormat` indeed parses `2022` as if the pattern letter had been `yyyy` even though it was `yy`. I admit I find that behaviour confusing. Related: [Java 8 DateTimeFormatter two digit year 18 parsed to 0018 instead of 2018?](https://stackoverflow.com/questions/48156022/java-8-datetimeformatter-two-digit-year-18-parsed-to-0018-instead-of-2018). – Ole V.V. May 22 '22 at 06:59

0 Answers0