Spring mvc Spring引导将表单数据解析为ZoneDateTime(dd/MM/yyyy HH:MM)

Spring mvc Spring引导将表单数据解析为ZoneDateTime(dd/MM/yyyy HH:MM),spring-mvc,spring-boot,java-time,datetime-parsing,zoneddatetime,Spring Mvc,Spring Boot,Java Time,Datetime Parsing,Zoneddatetime,我有一个具有java.time.ZonedDateTime属性的实体。我想将从dd/MM/yyyy HH:MM格式的表单提交的字符串解析为java.time.ZonedDateTime 我尝试了@DateTimeFormat(pattern=“dd/MM/yyyy HH:MM”)。但它只适用于LocalDate格式的@DateTimeFormat(pattern=“dd/MM/yyyy”)格式 我还创建了一个转换器,如下所示 public class ZonedDateTimeConverter

我有一个具有
java.time.ZonedDateTime
属性的实体。我想将从
dd/MM/yyyy HH:MM
格式的表单提交的字符串解析为
java.time.ZonedDateTime

我尝试了
@DateTimeFormat(pattern=“dd/MM/yyyy HH:MM”)
。但它只适用于
LocalDate
格式的
@DateTimeFormat(pattern=“dd/MM/yyyy”)
格式

我还创建了一个
转换器
,如下所示

public class ZonedDateTimeConverter implements Converter<String, ZonedDateTime> {

    private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm");

    private final ZoneId zoneId;

    public ZonedDateTimeConverter(ZoneId zoneId) {
        this.zoneId = zoneId;
    }

    @Override
    public ZonedDateTime convert(String source) {
        LOG.info("Parsing string {} to ZonedDateTime: {}", source, ZonedDateTime.parse(source, DATE_TIME_FORMATTER));
        return ZonedDateTime.parse(source, DATE_TIME_FORMATTER);
    }
}
我不确定什么是正确的方法使它工作。
使用弹簧靴1.5.6。Thymeleaf 3.0.7

您的
DateTimeFormatter
模式只有日期(
dd/MM/yyyyy
)和时间(
HH:MM
),但是
ZonedDateTime
也需要直接解析时区

由于输入没有,一种替代方法是首先将输入解析为
java.time.LocalDateTime
,然后使用您已有的
zoneId
将其转换为
ZoneDateTime

public ZonedDateTime convert(String source) {
    // parse to LocalDateTime
    LocalDateTime dt = LocalDateTime.parse(source, DATE_TIME_FORMATTER);
    // convert to ZonedDateTime
    return dt.atZone(this.zoneId);
}

另一种选择是在格式化程序中设置时区,这样就可以直接解析为
ZonedDateTime
。但是在本例中,我还建议您进行重构:将格式化程序设置为转换器类的字段(而不是
静态
字段),因为它将取决于在构造函数中传递的
ZoneId

public class ZonedDateTimeConverter implements Converter<String, ZonedDateTime> {

    private final DateTimeFormatter formatter;

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

    @Override
    public ZonedDateTime convert(String source) {
        // now the formatter has a zone set, so I can parse directly to ZonedDateTime
        return ZonedDateTime.parse(source, this.formatter);
    }
}
公共类ZonedDateTimeConverter实现转换器{
专用最终日期时间格式化程序;
公共ZonedDateTime转换器(ZoneId ZoneId){
//在格式化程序中设置区域
this.formatter=DateTimeFormatter.of模式(“dd/MM/yyyy HH:MM”)。带区域(zoneId);
}
@凌驾
公共分区DateTime转换(字符串源){
//现在格式化程序有一个区域集,所以我可以直接解析到ZoneDateTime
返回zoneDateTime.parse(源,this.formatter);
}
}

请注意使用
ZoneId.systemDefault()
。此方法获取JVM的默认时区,但请记住,因此最好始终指定要使用的时区

API使用的格式(始终为
大陆/城市
,如
亚洲/加尔各答
欧洲/柏林
)。然后使用
of
方法创建时区,例如
ZoneId.of(“亚洲/加尔各答”)

避免使用三个字母的缩写(如
IST
PST
),因为它们是。其中一些可能起作用(通常是由于复古兼容性的原因),但不能保证

您可以使用
ZoneId.getAvailableZoneIds()
获得所有可用时区的列表(并根据您的情况选择最佳时区)

public class ZonedDateTimeConverter implements Converter<String, ZonedDateTime> {

    private final DateTimeFormatter formatter;

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

    @Override
    public ZonedDateTime convert(String source) {
        // now the formatter has a zone set, so I can parse directly to ZonedDateTime
        return ZonedDateTime.parse(source, this.formatter);
    }
}