-1

I have to write a function to accept a list of date which are in different formated strings and return a list of Stringdates same format. I have tried the following code but some dates cannot parse. please help me to get the correct output.

 public static void main(String[] args) {
        List<String> dateList = new ArrayList<>();
        dateList.add("2010/03/30");
        dateList.add("15/12/2016");
        dateList.add("11-15-2012");
        dateList.add("20130720");
       changeDates(dateList);
    }

  public static List<String> changeDates(List<String> dates){
        List<String> returnedData = new ArrayList<>();

        dates.forEach(parsedDate ->{
            try {
                Date date1=new SimpleDateFormat("dd/MM/yyyy").parse(parsedDate);
                SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
                String yyyyMMdd = sdf.format(date1);
                System.out.println(yyyyMMdd);
            } catch (ParseException e) {
                e.printStackTrace();
            }
        });

        return returnedData;
    }

Output should be like this ["20100330","15122016","11152012","20130720"]

Thanks,

dasun_001
  • 139
  • 2
  • 3
  • 12
  • check the input format before parsing – fantaghirocco Nov 10 '20 at 14:25
  • I recommend you don’t use `SimpleDateFormat` and `Date`. Those classes are poorly designed and long outdated, the former in particular notoriously troublesome. Instead use `LocalDate` and `DateTimeFormatter`, both from [java.time, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/). – Ole V.V. Nov 10 '20 at 15:49
  • 1
    How do you want to interprete "10-11-2020"? As "MM-dd-yyyy" or as "dd-MM-yyyy"? – Meno Hochschild Nov 11 '20 at 08:56

1 Answers1

1

You cannot magically read every possible date format automatically. You have to choose some formats that you support.

When you have chosen a set of formats to support, you can try each of them on every date. When you find a parser that doesn't fail on the input, you use that one. Be careful with this though. You might end up in a situation where you, for example, parse the day of the month as a month (for example 01-02-2020 could in theory be interpreted as both 1st of February and 2nd of January 2020).

The following code works with Java 9 and above, I think. Note that I use the java.time library, instead of the old java.util.Date.

// These seemed to be the formats you used in your example. 
// "MM-dd-yyyy" is pretty weird I must say though.
private static final List<DateTimeFormatter> SUPPORTED_FORMATS = Arrays.asList(
        DateTimeFormatter.ofPattern("yyyy/MM/dd"),
        DateTimeFormatter.ofPattern("dd/MM/yyyy"),
        DateTimeFormatter.ofPattern("MM-dd-yyyy"),
        DateTimeFormatter.ofPattern("yyyyMMdd"));

private static final DateTimeFormatter OUTPUT_FORMAT = 
        DateTimeFormatter.ofPattern("yyyyMMdd");

public static Optional<LocalDate> tryParse(DateTimeFormatter formatter, String date) {
    try {
        return Optional.of(LocalDate.parse(date, formatter));
    } catch (DateTimeParseException e) {
        return Optional.empty();
    }
}

public static LocalDate parseSupportedDate(String date) {
    return SUPPORTED_FORMATS.stream()
            .flatMap(formatter -> tryParse(formatter, date).stream())
            .findFirst()
            .orElseThrow(() -> new IllegalArgumentException("Could not parse date " + date));
}

public static List<String> changeDates(List<String> dates) {
    return dates.stream()
            .map(date -> parseSupportedDate(date))
            .map(OUTPUT_FORMAT::format)
            .collect(Collectors.toList());
}
marstran
  • 26,413
  • 5
  • 61
  • 67