如何在数据库中保存未来(!)日期



这个问题是关于未来日期和时间的(对于过去的值UTC无疑是首选(。


我想知道是否有人对保存未来的"最佳"方法有任何建议>(,特别是在列可以从不同时区保持时间的上下文中。考虑到时区规则可能会更改UTC可能不是最佳选择。

到目前为止,我发现的最可行的选项是将其保存在该位置当地时间中的文本,以及该位置(例如" America/*"(。不幸的是,该解决方案可能更容易出现数据损坏,并且对于计算而言绝对不太方便。

有人会想到更好的东西吗?

预先感谢

首先,我以前详细介绍了这一点,因此请在这里和这里阅读我的答案,以及Lau Taarnskov的此博客文章。

对MySQL有特定的方面,您通常不想在未来事件的本地时间使用TIMESTAMP字段,因为它会在写入时从会话的时区转换为UTC,而是从UTC转换为会话的时区在阅读时间。即使这些是相同的时区ID(它们不必是(,也无法保证,在您编写数据和事件时,时区域的时区数据不会更改一个或两个时区发生。

相反,请使用DATETIME字段,该字段没有隐式时区转换。您将获得所写的确切价值。存储事件的本地时间,并存储一个包含活动时区标识符的VARCHAR字段。这是保留用户原始意图的唯一方法。

基本原理和边缘案例都在我之前给出的答案中描述了。

保存未来的Datestamp的注意事项与过去的Datestamp几乎相同。

(我称它们为 datestamps ,因为 DATETIMETIMESTAMP都是mysql中保留的单词。为了讨论,我想要一个并不意味着任何一个数据类型的单词。(

(

如果您正在构建一个系统以在多个时区使用的人使用,那么最好询问每个用户的时区域偏好,并将其存储在她的用户个人资料中。然后,当她登录时,您可以检索它,然后做

  SET time_zone = 'America/Halifax'

或其他任何内容,以用户的时区偏好命名。

如果您的MySQL Server在Linux,BSD或其他 *NIX系统上运行,则这些时区来自该机器上的ZoneInfo子系统。当各种国家司法管辖区改变时区规则时,ZoneInfo会更新。维护流行发行版的人通常会将更新推向Zoneinfo,因此您将是合理的最新信息。(如果您的MySQL Server在Windows主机上运行,请阅读该操作系统上的MySQL时区域的一些内容。保持最新情况更为麻烦。(

然后,如果您使用 TIMESTAMP数据类型为您的日托板,每当您检索值时,在显示之前,它会自动从UTC转换为本地时区。每当您存储一个值时,它会自动转换为UTC。在这方面,NOW()值类似于时间戳。因此,例如,如果您做

 UPDATE appointment
    SET datestamp = NOW() + INTERVAL 7 DAY
  WHERE id = something

您将存储一个UTC时间,这是此刻之后的一周。那如果你做

SELECT datestamp
  FROM appointment
 WHERE id = something

用户将在其本地时区中看到SET timezone的时间。

如果您使用DATETIME的数据类型用于日期开关,则可以在存储并检索它们时自行取代它们。存储它们时,将它们从当地时区取代到UTC。当您检索它们时,请另行。为此使用CONVERT_TZ()

 UPDATE appointment 
    SET datestamp = CONVERT_TZ(NOW(), 'America/Halifax', 'UTC') + INTERVAL 7 DAY
  WHERE id = something
SELECT CONVERT_TZ(datestamp, 'UTC', 'America/Halifax') datestamp
  FROM appointment
 WHERE id = something

显然,在这些查询中代替用户选择的'America/Halifax'的时区。

如果您可以避免它请勿参考当地时间从日光节省到标准时间,请参考当地时间。如果这样做,您将在应用程序一生的转换日内持续出现故障。我之所以知道这一点,是因为我继承了几个以这种方式工作的系统。馊主意。UTC:好主意。

相关内容

  • 没有找到相关文章

最新更新