简体   繁体   中英

How to convert HTML date to ZonedDateTime in SpringBoot/MVC/Web?

Im writing a code with spring boot, its a web project. Im also using thymeleaf and bootstrap.

I have a model that contains a ZonedDateTime variable called 'validade'. In my HTML/Thymeleaf file, I have a datepicker that allows you to pick day, month and year.

However, when I clicks submit, I get a spring boot error. How can I tell spring boot to convert this Date to ZonedDateTime? I cannot change this variable to LocalDate or LocalDateTime.

There was an unexpected error (type=Bad Request, status=400). Validation failed for object='tool'. Error count: 1 org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 errors Field error in object 'tool' on field 'validade': rejected value [2021-01-08]; codes [typeMismatch.tool.validade,typeMismatch.validade,typeMismatch.java.time.ZonedDateTime,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [tool.validade,validade]; arguments []; default message [validade]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.time.ZonedDateTime' for property 'validade'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [@org.springframework.format.annotation.DateTimeFormat @javax.persistence.Column java.time.ZonedDateTime] for value '2021-01-08'; nested exception is java.lang.IllegalArgumentException: Parse attempt failed for value [2021-01-08]]


<form method="POST" th:object="${tool}"  th:action="@{/tools/add}">
...
    <div lang="pt-br" class='date'>
                           
    <input th:value="${tool.validade}" th:field="${tool.validade}" lang="pt-br" id='data-validade' type='date' data-date-format="YYYY/MM/DD" class="form-control" />
    
    </div>
...
</form>

public class Tool{
...
    @DateTimeFormat(pattern = "dd-MM-yyyy")
    @Column(nullable = true, unique = false)
    private ZonedDateTime validade;

}

The pattern is not correct, according to your logs, the value 2021-01-08 was sent. That means that the date is following the pattern "yyyy-MM-dd".

The solution was to implement my own converter and inform spring boot of it. The code below solves the issue.

    import java.time.LocalDate;
    import java.time.ZoneId;
    import java.time.ZonedDateTime;
    import java.time.format.DateTimeFormatter;
    import org.springframework.boot.context.properties.ConfigurationPropertiesBinding;
    import org.springframework.core.convert.converter.Converter;
    import org.springframework.stereotype.Component;
    
    
@Component
@ConfigurationPropertiesBinding
public class ZonedDateTimeConverter implements Converter<String, ZonedDateTime> {

    @Override
    public ZonedDateTime convert(String source) {
        try {
            if (source == null) {
                return null;
            }
            
            if (source.contains(":") == false) {

                LocalDate ld = LocalDate.parse(source, DateTimeFormatter.ofPattern("yyyy-MM-dd"));

                ZonedDateTime atStartOfDay = ld.atStartOfDay(ZoneId.systemDefault());

                return atStartOfDay;
            } else {
                return ZonedDateTime.parse(source);
            }

        } catch (Exception ex) {
            //ex.printStackTrace();
        }

        return null;
    }

}

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