Reputation: 199
import org.springframework.format.annotation.DateTimeFormat;
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date etd;
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date eta;
This code works fine. But I found that an exception is thrown when the time is an empty string, so I add this:
@InitBinder
public void initBinder(ServletRequestDataBinder binder) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
dateFormat.setLenient(false);
binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
}
Now empty string convert to null, but only "yyyy-MM-dd" is used, and the hours and minutes are ignored.
For example, eta, before I add InitBinder, the value is '2020-11-11 11:11:11', after adding it is '2020-11-11 00:00:00'.
How to make spring continue to use the format on the DateTimeFormat annotation?
I found this question but he doesn't seem to use DateTimeFormat : How to handle different date formats in Spring MVC controller?
Upvotes: 2
Views: 1359
Reputation: 7808
Date
class is very much outdated (pun intended). Please switch to package java.time
and use one of the implementations of Temporal interface. In your case you should look at LocalDate and LocalDateTime classes. Then your @DateTimeFormat
will work correctly
Upvotes: 0
Reputation: 90547
Since Spring framework 5.3.5, @DateTimeFormat
supports defining a list of fallback patterns for parsing the date time if it fails to parse with the primary pattern. That means you could simply do :
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date etd;
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss",fallbackPatterns = "yyyy-MM-dd")
private Date eta;
Upvotes: 3
Reputation: 7656
I don't think that you can use both together, as only one of them will be picked by the system, but what you can do is extend standard behavior and add empty string processing.
As I like the declarative way of parsing strings based on the @DateTimeFormat
annotation I will share the code which shows how easy it is to extend default functionality.
So to start with Spring uses AnnotationFormatterFactory
s that create formatters to format and parse values of fields annotated with a particular annotation. The @DateTimeFormat
annotation has several AnnotationFormatterFactory
s but one which parses and formats the java.util.Date
s is DateTimeFormatAnnotationFormatterFactory
, so what we need to do is just override it add our custom handling and register the formatter. Its is pretty straightforward to do that via WebMvcConfigurationSupport
.
@Configuration
public class WebConfig extends WebMvcConfigurationSupport {
@Override
protected void addFormatters(FormatterRegistry registry) {
registry.addFormatterForFieldAnnotation(new DateTimeFormatAnnotationFormatterFactory(){
@Override
public Parser<?> getParser(DateTimeFormat annotation, Class<?> fieldType) {
var defaultParser = super.getParser(annotation, fieldType);
return (Parser<Object>) (text, locale) -> {
// if the text value is empty just return null and do not try to parse
if(!StringUtils.hasText(text)){
return null;
}
return defaultParser.parse(text, locale);
};
}
});
}
}
Upvotes: 0