Java date time format check and reset

霸气de小男生 提交于 2019-12-06 12:48:00

问题


String is an input and i have to check whether it is in any of these formats. If it is in sdf1 format then pass, if it is in sdf2,3.... then i add the missing the format and parse it with sdf1 format

SimpleDateFormat sdf1 = new SimpleDateFormat("MM/dd/yyyy hh:mm:ss a");
SimpleDateFormat sdf2 = new SimpleDateFormat("MM/dd/yyyy hh:mm:ssa");
SimpleDateFormat sdf3 = new SimpleDateFormat("MM/dd/yyyy hh:mm a");
SimpleDateFormat sdf3 = new SimpleDateFormat("MM/dd/yyyy hh:mma");
SimpleDateFormat sdf3 = new SimpleDateFormat("MM/dd/yyyy hh:mm");
SimpleDateFormat sdf3 = new SimpleDateFormat("MM/dd/yyyy"); 

Here is what i have

try{
            // Parse if it is MM/dd/yyyy hh:mm:ss a
            cal = Calendar.getInstance();
            cal.setTime(sdf1.parse(inStr));
          }catch(Exception exp){
             try{
               cal = Calendar.getInstance();
               //Parse if it is MM/dd/yyyy hh:mm:ssa                      
               sdf2.parse(inStr);                 
               inStr = new StringBuilder(inStr).insert(str.length()-2, " ").toString();
               cal.setTime(sdf1.parse(inStr));
              }catch(Exception dte2){
                try{
                    cal = Calendar.getInstance();
                    //Parse if it is MM/dd/yyyy hh:mma
                    sdf3.parse(inStr);
                    //if pass then set 00:00:00 AM
                    inStr = inStr+" AM";
                    inStr = new StringBuilder(inStr).insert(str.length()-2, ":00").toString();
                    cal.setTime(sdf1.parse(inStr));

it keeps going like try parsing and if failed in exception block check for the next one. Is there any easy way to do this, may be in JAVA 8? i could use the link from marked as duplicate it talks about how to parse, but i have additional requirement as auto complete with missing format.


回答1:


In Java 8, you can use a java.time.format.DateTimeFormatter with lots of optional sections - delimited by []:

DateTimeFormatter fmt = DateTimeFormatter
    .ofPattern("MM/dd/yyyy[ hh:mm[[:ss][ ]a]][HH:mm]", Locale.US);

If you want just to validate the inputs - and don't assign the result to a date/time variable - just calling parse is enough. This works for all the cases below:

fmt.parse("10/20/2018");
fmt.parse("10/20/2018 10:20");
fmt.parse("10/20/2018 10:20AM");
fmt.parse("10/20/2018 10:20 AM");
fmt.parse("10/20/2018 10:20:30AM");
fmt.parse("10/20/2018 10:20:30 AM");

If the input is invalid, it'll throw a DateTimeParseException.

Note that there's a difference between HH and hh. H is for hour-of-day (values between 0 and 23), while h is for clock-hour-of-am-pm (values between 1 and 12). H can't be with AM/PM designator, while h must have AM/PM to disambiguate it. That's why there are 2 different optional sections, one with each field.

I also use Locale.US because AM/PM strings are localized. Although for most locales, the result is "AM" or "PM", for some others it can be lowercase ("am"), or some other values (午後 in Japanese, for example).

If you don't set the locale, it uses the JVM default. But I prefer to set it a specific one that I know it'll work with the inputs I have.


To print those values again, with all the fields, it's a little bit tricky. The inputs can have only a date (day, month, year), or a date and time (day, month, year, hour, minute), so one alternative is to use a LocalDateTime (and set the missing fields when not present).

You can use parseBest and then check the type that was parsed:

// parse, try to create a LocalDateTime - if it's not possible, try a LocalDate
TemporalAccessor parsed = fmt.parseBest("10/20/2018", LocalDateTime::from, LocalDate::from);
LocalDateTime dt = null;
if (parsed instanceof LocalDateTime) {
    // LocalDateTime parsed (all fields set)
    dt = (LocalDateTime) parsed;
} else if (parsed instanceof LocalDate) {
    // LocalDate parsed (set time fields)
    dt = ((LocalDate) parsed)
        // set time (use whatever value you want - I'm using 10 AM as example)
        .atTime(LocalTime.of(10, 0));
}

Then you use another formatter for output - that's because the first formatter will print all the optional sections when formatting, so it'll print the hours twice. Just create another one and that's it:

DateTimeFormatter outputFmt = DateTimeFormatter.ofPattern("MM/dd/yyyy hh:mm:ss a", Locale.US);
System.out.println(dt.format(outputFmt)); // 10/20/2018 10:00:00 AM


来源:https://stackoverflow.com/questions/49678922/java-date-time-format-check-and-reset

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!