将 Instant 序列化和反序列化为 `yyyy-MM-dd`

Serialize and deserialize a Instant as `yyyy-MM-dd`

我有一个 POST API 像这样:

    @JsonDeserialize(using = MyCustomDeserializer.class)
    @JsonSerialize(using = MyCustomSerializer.class)
    @NotNull(message = "fromDate should not be blank!")
    @FutureOrPresent(message = "fromDate must be of Future or Present")
    private Instant fromDate;

我的实用程序包中有像这样的自定义序列化器和反序列化器:

public class MyCustomSerializer extends JsonSerializer<Instant> {
    private DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd").withZone(ZoneOffset.UTC);

    @Override
    public void serialize(Instant value, JsonGenerator gen, SerializerProvider serializers) throws IOException, JsonProcessingException {
        String str = fmt.format(value);

        gen.writeString(str);
    }
}
public class MyCustomDeserializer extends JsonDeserializer<Instant> {

    private DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd").withZone(ZoneOffset.UTC);

    @Override
    public Instant deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
        LocalDate date = LocalDate.parse(p.getText());
        return Instant.from(fmt.parse(date.toString()));
    }
}

我想在内部保存时间组件作为一天的开始。 API 应该只接收和输出 date

我尝试将 转换为 Instant。有人可以帮助我怎么做吗(在数据库中存储为 date+start_of_day)和 expose/consume 作为 yyyy-MM-dd?

TL;DR

    return date.atStartOfDay(ZoneOffset.UTC).toInstant();

(未经测试,如有错别字请见谅)

详情

您真的是在尝试将方钉装入圆孔中。一个Instant是一个时间点,在那个时间点,是两个或三个不同时区的不同日期。解决 UTC 有帮助,然后我们可以让它工作。它仍然不理想。差异的标准解决方案(hack)是将日期表示为某个时区的一天的开始,UTC 是一个很好的选择。

为什么你的代码不起作用

在反序列化器中解析日期(格式化后)会给出日期和 UTC 偏移量,但不会给出一天中的时间。我们需要这三者都确定一个明确的时间点。相反,在我的代码中,我明确指定了一天的开始。