Search code examples
javaspringdate-format

@DateTimeFormat does work only to limited pattern. Why is it happening?


I am making a form that receives two registration dates to find the list of the uses who registered between the inserted dates.

To bind the input from the form to the data of the type LocalDateTime of the Command instance, I use @DateTimeFormat annotation in my command instance, however, only one pattern works in this code.

Only the yyyyMMddHH pattern work without an exception. Other patterns such as yyyy-MM-dd, yyyy/MM/dd, and more don't work.

They throw an exception like the following

Failed to convert property value of type java.lang.String to required type java.time.LocalDateTime for property from; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [@org.springframework.format.annotation.DateTimeFormat java.time.LocalDateTime] for value 2020-08-13; nested exception is java.lang.IllegalArgumentException: Parse attempt failed for value [2020-08-13]

This is the code for the command instance,

public class UserSearchByRegDateRequest {
    
    @DateTimeFormat(pattern = "yyyyMMddHH")
    private LocalDateTime from;
    @DateTimeFormat(pattern = "yyyyMMddHH")
    private LocalDateTime to;
    
    public LocalDateTime getFrom() {
        return from;
    }
    public void setFrom(LocalDateTime from) {
        this.from = from;
    }
    public LocalDateTime getTo() {
        return to;
    }
    public void setTo(LocalDateTime to) {
        this.to = to;
    }
}

Code for the form

<body>

    <h2><spring:message code="regDateSearchFormTitle"/></h2>
    
    <spring:message code="dateFormatInstruction"/><br/><br/>
    
    <form:form action="processSearch" modelAttribute="searchCommand">
        
        <label> 
            <form:input path="from"/><spring:message code="from"/>
            <form:errors path="from"/>
        </label>
            
        <label>
            <form:input path="to"/><spring:message code="to"/>
            <form:errors path="to"/>
        </label>
            
        <input type="submit" value="search"/>
    </form:form>
    
    <c:if test="${!empty members}">
        <table>
            <tr>
                <th><spring:message code="search.id"/></th>
                <th><spring:message code="search.name"/></th>
                <th><spring:message code="search.email"/></th>
                <th><spring:message code="search.regDate"/></th>
            </tr>

        <c:forEach var="member" items="${members}">
            <tr>
                <td>${member.id}</td>
                <td>${member.name}</td>
                <td>${member.email}</td>
                <td><tf:formatDateTime value="${member.registerDateTime}" pattern="yyyy-MM-dd"/></td>
            </tr>
        </c:forEach>
        
        </table>
    </c:if>
</body>

Solution

  • Since you're trying to convert only date "2020-08-13" without time specified you should use LocalDate with format as such:

    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private LocalDate from;
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private LocalDate to;
    

    You can then convert a string with format "2020-08-13" into LocalDate without exception being thrown.