【问题标题】:Java SQL date is off by 1 dayJava SQL 日期差 1 天
【发布时间】:2020-08-17 01:12:48
【问题描述】:

我正在使用与我位于同一时区的 MySQL 服务器。我试图在DATE 类型的列上使用以下代码将 java.util.Date 插入数据库:

SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); dateFormat.setTimeZone(TimeZone.getTimeZone("GMT+2")); Date date = dateFormat.parse(map.value("date"));

插入“日期”的位置。问题是在数据库中查找时日期差了一天。示例:我插入了 2020-05-02,数据库显示 2020-05-01。这产生了一个问题,当我想获得日期为 2020-05-02 的匹配项时,我必须提前 1 天搜索我不想做的事情。 这也发生在一天中的特定时间之间,所以我假设它是一个时区问题,但我不知道如何解决它!

提示?

【问题讨论】:

  • 避免java.util.Date;在内部,它只不过是一个long,它表示自 1970 年 1 月 1 日午夜 UTC 以来的毫秒数。它早已被java.time 包中的LocalDateTime 取代。当我现在需要在数据库中插入时,我会使用now()
  • 可能解决不了你的问题,建议不要使用SimpleDateFormatDate。这些类设计不佳且早已过时,尤其是前者,尤其是出了名的麻烦。相反,只需使用来自java.time, the modern Java date and time APILocalDate。没错,这肯定是时区问题。
  • 您的列的数据类型究竟是什么?

标签: java mysql sql date


【解决方案1】:

对于仅日期值,没有时间和时区,您应该在定义列时使用 MySQL 类型 DATE。此类型与 SQL 标准中定义的 DATE 类型匹配。

在 Java 端,永远不要使用java.util.Date。该类是与 Java 的最早版本捆绑在一起的可怕日期时间类的一部分。它们在多年前被 JSR 310 中定义的 java.time 类所取代。

对于 Java 中的仅日期值,请使用 java.time.LocalDate

在您的地图中,您应该存储LocalDate 对象而不仅仅是字符串。但如果必须,您可以解析和生成字符串。您的字符串格式似乎与 ISO 8601 中定义的标准格式一致。java.time 类默认使用这些标准格式。所以不需要指定格式模式。

LocalDate localDate = LocalDate.parse( "2021-01-23" ) ;

java.time 类的对象可以通过使用符合JDBC 4.2 及更高版本的JDBC driver 与您的数据库进行交换。

将其写入数据库。

myPreparedStatement.setObject( … , localDate ) ;

从数据库中检索。

LocalDate localDate = myResultSet.getObject( … , LocalDate.class ) ;

使用上面显示的方法使时区变得无关紧要:LocalDate 通过 JDBC 4.2 或更高版本在 MySQL DATE 类型的列上 - 也就是说,除非您的 JDBC driverbuggy(错误 #30877755):请参阅Answer by Teh Swish.

【讨论】:

  • 我按照你说的做了,但它仍然显示在前一天的数据库中。当我将日期传递给数据库并将其返回给我的应用程序时,它会显示正确的日期。如果这很重要,我将使用 activejdbc 进行数据库事务。我可以在我的代码中添加一天来弥补这一点,但我觉得那不可行......
  • 我现在通过在插入时添加一天和获取时添加一天来修复它。似乎至少现在可以工作。
  • @TehSwish 我再问一遍:究竟你的列的数据类型是什么?
  • 类型是日期
【解决方案2】:

此问题来自 java 中的 MySQL 连接器。版本 8.0.19 使用 JVM 时区转换日期,这会导致 1 天休假问题。这在 8.0.20 补丁中得到解决。阅读这里https://dev.mysql.com/doc/relnotes/connector-j/8.0/en/

【讨论】:

  • 很好地展示了在他们的 JDBC 驱动程序中修复的错误。经过修复,我在my Answer 中展示的方法应该可以避免时区影响您的日期的进一步问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-20
  • 2011-03-20
  • 2011-04-19
  • 2015-12-19
  • 2016-04-16
  • 2012-09-09
相关资源
最近更新 更多