【问题标题】:How to store datetimes in UTC and local timezone如何在 UTC 和本地时区中存储日期时间
【发布时间】:2011-06-06 05:24:13
【问题描述】:

什么是存储日期时间的实用方法,以便我可以让用户查看/查询他们自己本地时间的数据,同时保留有关原始日期时间的信息。

基本上,用户希望能够查询(以他们自己的本地时间为准)从不同时区的系统收集的数据。但有时,他们想知道原始系统中的数据是在 18:00 创建的。当来自世界不同地区的用户就同一事件进行交流时,它会有所帮助。

User1: What? We don't have any data for 20:00
User2: Dude, it says 20:00 right there on my screen.
User1: Wait, what timezone are you? What's the UTC-time?
User2: What is UTC? Is that something with computers?
User1: OMFG! *click*

我正在寻找有关如何存储数据的建议。

我正在考虑将所有日期时间存储在 UTC 中,并添加一个包含原始时区名称的附加列,其形式允许我使用 mysql CONVERT_TZ 或 Java 中的对应项。然后,应用程序会将用户输入的日期转换为 UTC,我可以轻松地查询数据库。所有日期也可以在应用程序中轻松转换为用户本地时间。使用原始时区列,我还可以显示原始日期时间。

但是,这意味着对于我拥有的每个日期时间,我都需要一个额外的列...

start_time_utc datetime
start_time_tz  varchar(64)
end_time_utc   datetime
end_time_tz    varchar(64)

我在正确的轨道上吗?

是否有使用过此类数据的人分享他们的经验?

(我将使用 MySQL 5.5 CE)

更新 1

数据将以 xml 文件的形式传递,其中每个条目在某个本地时区都有一个日期时间。所以只会有一个插入进程,在一个地方运行。

一旦加载到数据库中,它将在一些 Web 应用程序中呈现给不同时区的用户。对于大多数用例,感兴趣的数据也确实来自与查看数据的用户相同的时区。对于一些更复杂的用例,一系列事件相互关联,跨越多个时区。因此,用户希望能够谈论这些事件,以便在对方的时间调查可能的原因/后果。不是 UTC,不是他们自己的当地时间。

【问题讨论】:

  • 对于手头的问题,我相信你的解决方案是好的。
  • MySQL 没有DateTimeOffset,比如 MSSQL(一种指定时间戳及其与 UTC 的偏移量的数据类型)吗?如果不是,那么您的解决方案是最接近的等价物,仅在所需字段的数量上有所不同(1 对 2)。
  • 不,MySQL 不支持 TIMESTAMP WITH TIMEZONE(这是 ANSI 数据类型)
  • @horse,我一直在寻找类似的东西(我在 Oracle 中尝试过),但在 MySQL 中找不到。你有使用 MySQL 中“时区”数据的经验吗?
  • 不,我没有。幸运的是我不需要经常使用 MySQL。

标签: mysql datetime database-design timezone convert-tz


【解决方案1】:

由于用户可以生活在不同的时区,甚至可以从一个时区移动到另一个时区,因此最佳做法是将日期和时间以 UTC 格式存储,并在显示时转换为用户的时区。

【讨论】:

    【解决方案2】:

    手册有一个专门用于此的部分,关于时间戳:

    TIMESTAMP 值是从 UTC 的当前时区 存储,并从 UTC 转换回来 到当前时区 恢复。 (这仅发生在 TIMESTAMP 数据类型,不适用于其他 类型,例如 DATETIME。)默认情况下, 每个的当前时区 连接是服务器的时间。这 时区可以设置在 每个连接的基础,如中所述 第 9.6 节,“MySQL 服务器时区 支持”。只要时区 设置保持不变,你回来 您存储的相同值。如果你存储 TIMESTAMP 值,然后更改 时区并检索值, 检索到的值不同于 您存储的值。发生这种情况是因为 没有使用相同的时区 双向转换。这 当前时区可作为 time_zone 系统的值 变量。

    http://dev.mysql.com/doc/refman/5.5/en/timestamp.html

    所以你可以在客户端使用:SET time_zone = timezone; 来设置时区。然后所有查询都会将时间戳转换为正确的时区。在Java中不需要做任何复杂的事情,除了设置时区(我认为甚至可能是JDBC连接字符串中的参数)

    【讨论】:

    • 我仍然需要存储原始时区,以便在另一个本地时区显示它(见对话)。
    • 也许我理解错了。因此,就像 Eldad 所说,将原始时区与列一起存储是您唯一的选择...
    【解决方案3】:

    您始终可以将祖鲁时间作为所有计算的基础。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-10-29
      • 2018-05-08
      • 2010-10-05
      • 2019-06-15
      • 2022-08-15
      • 2016-10-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多