How to display ZonedDateTime on HTML5 datetime-local input with Thymeleaf?

30 Views Asked by At

How to display ZonedDateTime on HTML5 datetime-local input with Thymeleaf? The ExampleModel.datetime is able to convert from HTML datetime-local input with ZonedDateTimeConverter, but unable to display on the HTML datetime-local input, it is always empty.

html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Zoned Date Time</title>
</head>
<body>
    <form action="#" th:action="@{/example/}" th:object="${exampleModel}"
        method="post">
        <p>
            Text: <input type="text" th:field="*{text}" />
        </p>
        <p>
            Date Time: <input type="datetime-local" th:field="*{datetime}" />
        </p>
        <p>
            <input type="submit" value="Save" />
        </p>
    </form>
</body>
</html>

Model

package com.example.springboot.model;

import java.time.ZonedDateTime;

import lombok.Data;

@Data
public class ExampleModel {
    private String text;
    private ZonedDateTime datetime;

    public ExampleModel() {

    }

    public ExampleModel(String text, ZonedDateTime datetime) {
        this.text = text;
        this.datetime = datetime;
    }

}

Controller

package com.example.springboot.ctrl;

import java.time.ZonedDateTime;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import com.example.springboot.model.ExampleModel;

@Controller
@RequestMapping("/example/")
public class ExampleCtrl {
    private static final Logger log = LoggerFactory.getLogger(ExampleCtrl.class);

    @GetMapping()
    public String doGet(Model model) {
        model.addAttribute("exampleModel", new ExampleModel("Hello", ZonedDateTime.now()));

        log.debug("model: {}", model);
        return "example";
    }

    @PostMapping()
    public String doPost(@ModelAttribute ExampleModel exampleModel, Model model) {
        log.info("exampleModel: {}", exampleModel);

        return "example";
    }

}

ZonedDateTimeConverter

package com.example.springboot;

import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.convert.converter.Converter;

final class ZonedDateTimeConverter implements Converter<String, ZonedDateTime> {
    private static final Logger log = LoggerFactory.getLogger(ZonedDateTimeConverter.class);

    private final DateTimeFormatter dtf;

    public ZonedDateTimeConverter(ZoneId zoneId) {
        // set the zone in the formatter
        this.dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm").withZone(zoneId);
    }

    @Override
    public ZonedDateTime convert(String source) {
        return ZonedDateTime.parse(source, this.dtf);
    }

}

WebConfig

package com.example.springboot;

import java.time.ZoneId;

import org.springframework.context.annotation.Configuration;
import org.springframework.format.FormatterRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addConverter(new ZonedDateTimeConverter(ZoneId.systemDefault()));
    }
}
0

There are 0 best solutions below