简体   繁体   中英

How to format String that accepts a date of any input format?

How would I go about formatting a String that accepts any input?

The user could enter "11/9/2017", "11/09/17" or "11/09/2017".

I'm trying to force the output to include the dashes, like "11-10-2017".

What I've tried:

public static String dateFormatter(String date){
    date.replace("-", "");
    date.replace("/", "");
    Date _date = null;

    SimpleDateFormat df = new SimpleDateFormat("MM-dd-yyyy");
    try {
        _date = df.parse(date);

        return _date.toString();
    } catch (Exception ex){
        ex.printStackTrace();
    }

    return null;
}

What happens: I get a parse exception:

"java.text.ParseException: Unparseable date: "11232017" (at offset 8)"

Remove date.replace("-", ""); and change date.replace("/", ""); to date = date.replace("/", "-"); .

Ref: SimpleDateFormat 's - parse() and format()

You need to do 3 things here.

  1. Understand the format of string that you are receiving.
  2. Parse your input string with a formatter and get a valid Date object.
  3. Format it back to what you are expecting.

     public static String dateFormatter(String dateString) {
            Date _date = null;
            SimpleDateFormat inputDateFormat = new SimpleDateFormat("MM/dd/yy");
            SimpleDateFormat outputDateFormat = new SimpleDateFormat("MM-dd-yyyy");
            try {
                _date = inputDateFormat.parse(dateString);
                return outputDateFormat.format(_date);
            } catch (Exception ex) {
                ex.printStackTrace();
            }
            return _date;
        }

When it comes to date conversion from a string which can be of any format, it gets complicated.

I would recommend you take following approach ...

  • Use latest Java 8 Date Time APIs to format date
  • Using Pattern matching, restrict the date input formats by accepting only certain date formats (eg do not accept 2 digit year)
  • Handle invalid dates (leap year etc.) and bad formatted dates separately and take appropriate action

NOTE: Pattern matching ensures that your input string has / correctly placed so that we can extract integers (month, day and year) from given string


import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Pattern;

public class DateFormat {

    public static void main(String[] args) {
        List<String> dates = Arrays.asList("11/9/2017","11/09/17", "11/09/2017", "02/29/2017");
        // accepts 1-9 or 01-09 or 10-12 as month
        String month = "([1-9]|0[1-9]|1[0-2])";
        // accepts 1-9 or 01-09 or 10-19 or 20-29 or 30-31 as day
        String day = "([1-9]|0[1-9]|1[0-9]|2[0-9]|3[0-1])";
        // accepts 1900-1999 or 2000-2099 as year
        String year = "(19[0-9][0-9]|20[0-9][0-9])";
        // switch the regex as you like depending on your input format
        // e.g. day + "\\/" + month + "\\/" + year etc.
        Pattern pattern = Pattern.compile(month + "\\/" + day + "\\/" + year);
        for (String dateValue : dates) {
            if (pattern.matcher(dateValue).matches()) {
                try {
                    // pattern matching ensures you don't get StringIndexOutOfBoundsException
                    // LocalDate.of(year, month, dayOfMonth)
                    LocalDate date = LocalDate.of(Integer.parseInt(dateValue.substring(dateValue.lastIndexOf('/') + 1)), 
                            Integer.parseInt(dateValue.substring(0, dateValue.indexOf('/'))), 
                            Integer.parseInt(dateValue.substring(dateValue.indexOf('/') + 1, dateValue.lastIndexOf('/'))));
                    System.out.println(String.format("Correct Format : %-10s ==> %s", dateValue, date.format(DateTimeFormatter.ofPattern("MM-dd-yyyy"))));
                // DateTimeException and DateTimeParseException will be covered here for invalid dates
                } catch (Exception e) {
                    System.out.println(String.format("Invalid Date   : %s", dateValue));
                }
            } else {
                System.out.println(String.format("Bad Format     : %s", dateValue));
            }
        }
    }
}

Sample Run:

Correct Format : 11/9/2017  ==> 11-09-2017
Bad Format     : 11/09/17
Correct Format : 11/09/2017 ==> 11-09-2017
Invalid Date   : 02/29/2017

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM