How to handle different date formats in Spring MVC

2020-07-17 06:20发布

Is it possible to handle different date format in a Spring MVC controller?

I know that setting something like this

@InitBinder
protected void initBinder(WebDataBinder binder) {
    SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
    binder.registerCustomEditor(Date.class, new CustomDateEditor(
            dateFormat, false));
}

I can handle dd/MM/yyyy format, but what if i want to parse also dates in yyyyMMddhhmmss format? Should I add multiple CustomDateEditors in my controller?

6条回答
再贱就再见
2楼-- · 2020-07-17 06:50

If at a time you receive only one format of date, then you could simply create one instance of DateFormat based on format

for example

Decide the format based on the input

DateFormat df = null;
if(recievedDate.indexOf("//")!=-1){
    df = new SimpleDateFormat("dd/MM/yyyy")
}else{
    df = new SimpleDateFormat("yyyyMMddhhmmss")
}
查看更多
Fickle 薄情
3楼-- · 2020-07-17 06:51

If you need it only at puntual cases, you can register the custom editor attached to a field in the form:

DateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy", this.getLocale(context));
DateFormat dateTimeFormat = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss SSS", this.getLocale(context));
binder.registerCustomEditor(Date.class, new CustomDateEditor(dateTimeFormat, true));
binder.registerCustomEditor(Date.class, "name.of.input", new CustomDateEditor(dateTimeFormat, true));
查看更多
不美不萌又怎样
4楼-- · 2020-07-17 06:51

Inspired by Skipy

public class LenientDateParser extends PropertyEditorSupport {

private static final List<String> formats = new ArrayList<String>();

private String outputFormat;

static{
    formats.add("dd-MM-yyyy HH:ss");
    formats.add("dd/MM/yyyy HH:ss");
    formats.add("dd-MM-yyyy");
    formats.add("dd/MM/yyyy");
    formats.add("dd MMM yyyy");
    formats.add("MMM-yyyy HH:ss");
    formats.add("MMM-yyyy");
    formats.add("MMM yyyy");
}

public LenientDateParser(String outputFormat){
    this.outputFormat = outputFormat;
}

@Override
public void setAsText(String text) throws IllegalArgumentException {
    if(StringUtils.isEmpty(text))
        return;
    DateTime dt = null;
    for(String format : formats){

        try{

            dt = DateTime.parse(text, DateTimeFormat.forPattern(format));

            break;

        }catch(Exception e){
            if(log.isDebugEnabled())
                log.debug(e,e);
        }
    }
    if(dt != null)
        setValue(dt.toDate());
}

@Override
public String getAsText() {
    Date date = (Date) getValue();

    if(date == null)
        return "";

    DateTimeFormatter f = DateTimeFormat.forPattern(outputFormat);

    return f.print(date.getTime());

}
}
查看更多
不美不萌又怎样
5楼-- · 2020-07-17 06:53

For others having the same question, if you are using spring 3 You can use the awesome @DateTimeFormat(pattern="dd-MM-yyyy") in the field of your model.

Just make sure to register a conversionService with your org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter

You can have as much as you want of @DateTimeFormat in the same bean.

查看更多
聊天终结者
6楼-- · 2020-07-17 06:56

How about this. the above can go out of whack pretty soon.

       public class MostLenientDateParser {
           private final List<String> supportedFormats;

           public MostLenientDateParser(List<String> supportedFormats) {
               this.supportedFormats = supportedFormats;
           }

           public Date parse(String dateValue) {
               for(String candidateFormat: supportedFormats) {
                   Date date = lenientParse(dateValue, candidateFormat);
                   if (date != null) {
                       return date;
                   }
               }
               throw new RuntimeException("tried so many formats, non matched");
           }

           private Date lenientParse(String dateCandidate, String dateFormat) {
               try {
                   return new SimpleDateFormat(dateFormat).parse(dateCandidate);
               } catch (Exception e) {
                   return null;
               }
           }
       }

This could also be referenced through Spring Converters via a CustomDateEditor implementation for form-data binding.

查看更多
够拽才男人
7楼-- · 2020-07-17 07:09

Not a great idea to have lenient date formatters when dealing with multiple locales. A date like 10/11/2013 will get parsed correctly with both dd/MM/YYYY and MM/dd/YYYY

查看更多
登录 后发表回答