通过 Jackson 序列化 java.sql.Date,同时考虑夏令时

我正在使用 ajava.sql.Date将日期字段存储在我的一个域对象中。此字段映射到 MySQLDATE列。当我尝试通过杰克逊将此字段序列化为 JSON 时,杰克逊似乎没有考虑夏令时。


这是我的域对象中该字段的样子:


@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd", timezone = "EST")

private Date date;

如您所见,Jackson 已被指示将时区解释为 EST。我的 MySQL 数据库也使用 EST 时区:


SHOW VARIABLES LIKE '%zone';

Output:

system_time_zone | EST

time_zone        | SYSTEM

我的麻烦是,对于夏令时开始和结束之间的日期,杰克逊返回的日期比数据库中存储的日期少一天。我假设这是因为杰克逊没有考虑夏令时。


我通过尝试将Java 字段中的日期格式从yyyy-MM-dd更改为 来得出这个结论。yyyy-MM-dd HH:mm:ss我注意到服务器返回了类似的2017-03-13 00:00:00内容,但杰克逊将其序列化为2017-03-12 23:00:00(少一小时,这是夏令时影响的 EST 时间)。


有没有办法克服这个问题?另外,java.sql.Date考虑到它没有时间对应物,使用正确的类型吗?我一直在考虑java.time.LocalDate改用,但我还没有看到它是否会成功。


慕的地6264312
浏览 346回答 1
1回答

浮云间

博士永远不要使用java.sql.Date也不java.util.Date。仅使用java.time类。对于仅日期值,请使用LocalDate.您只会看到稳定的值,不受夏令时 (DST) 的影响。例子:LocalDate.parse( "2019-01-23" )java.sql.Date不是日期_我不确定到底是什么问题,但我怀疑这是由于您使用了可怕的java.sql.Date课程,因此没有实际意义。该类假装java.sql.Date代表一个仅限日期的值,没有时间和时区。然而,由于一些难以想象的糟糕设计决策,该类扩展了. 该课程确实有一个时间,并且是 UTC。更令人困惑的是,在它的源代码中隐藏了一个时区,没有 getter 和 setter,所以它似乎还没有影响像. 因此,尽管它的名称和目的是仅保存日期,但实际上确实将时间设置为 UTC。所以java.util.Datejava.util.Datejava.util.Dateequalsjava.sql.Datejava.sql.Date在调整一天中的时间方面有一些技巧,这可能是您遇到的问题。这些传统的日期时间课程是一大堆热气腾腾的……燕麦片。你永远不应该使用它们。引用该类的JavaDocjava.sql.Date:一个围绕毫秒值的瘦包装器,允许 JDBC 将其识别为 SQL DATE 值。毫秒值表示自 1970 年 1 月 1 日 00:00:00.000 GMT 以来经过的毫秒数。为了符合 SQL DATE 的定义,由 java.sql.Date 实例包装的毫秒值必须通过在实例关联的特定时区中将小时、分钟、秒和毫秒设置为零来“规范化” .顺便说一句,java.sql.Timestamp同样糟糕的是一团糟。它也笨拙地继承自,为纳秒java.util.Date添加了第二个小数秒。也避免使用此类,现在由java.time.Instantor代替java.time.OffsetDateTime。同样,java.sql.Time替换为java.time.LocalTime。java.time.LocalDate真的是约会随着 JSR 310 和 JDBC 4.2 的采用,您可以使用现代行业领先的java.time类。到目前为止,Jackson 可能已更新为使用java.time。如果没有,请参阅此问题以获取指向杰克逊中处理java.time的数据类型模块的链接。看起来您的输入字符串采用标准ISO 8601格式,YYYY-MM-DD。java.time类在解析/生成表示日期时间值的字符串时默认使用标准格式。对于仅日期使用,LocalDate真正是没有时间的日期的类,并且没有区域/偏移量。您将看到不受夏令时 (DST)影响的稳定日期值。解析。LocalDate ld = LocalDate.parse( "2019-01-23" ) ;店铺。myPreparedStatement.setObject( … , ld ) ;取回。LocalDate ld = myResultSet.getObject( … , LocalDate.class ) ;
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java