【问题标题】:Retrieve UTC times added during daylight savings检索夏令时期间添加的 UTC 时间
【发布时间】:2015-04-09 01:38:38
【问题描述】:

我有一个表,用户可以在其中存储和事件。事件的开始时间存储在一个列中,列字段为time。在夏令时期间,我所在的时间偏移量是-5,因此如果用户存储一个从12:00pm 开始的事件,它将作为17:00:00 存储在数据库中。如果用户要创建一个具有完全相同的开始时间而不是夏令时的事件,则时区偏移量将为-4,并将作为16:00:00 存储在数据库中。

如果用户选择从下午 12:00 开始的所有事件并且是夏令时,我将使用 javascript(在本例中为 -5)获取用户时区偏移量,并相应地创建查询 WHERE startTime > 17:00:00。问题是在不是夏令时时创建的所有事件的开始时间都是16:00:00,因为偏移量是-4 而不是-5,所以它们不会被选中。

有解决这个问题的办法吗?我存储事件开始时间的方法是否完全错误?

【问题讨论】:

  • 你在哪里进行 UTC 转换?
  • 在添加事件之前的 php 中。
  • 有什么特殊原因你不只使用utc_timestamp() 作为插入值吗?
  • 问题是它们的UTC时间不同,但本地时间相同。因此,使用本地时间存储它们,或者在创建它们时为适用的偏移量设置第二列,以便您可以调整到本地时间,类似于“其中 UTC+offset = 17:00”但当然是在有效的 SQL 中。
  • 我认为最快的解决方法是过度查询额外的时间并使用 UTC 补偿日期过滤客户端(js 可以根据日历调整 DST)。假设您在响应中的完整项目中有真实日期。就像两次犯同样的错误以抵消两者一样。

标签: javascript php mysql sql


【解决方案1】:

如果您有DATETIME 值,并且知道记录这些日期和时间时使用的地理时区,则可以使用CONVERT_TZ() 从本地时间数据中检索UTC 时间。

首先使用ADDTIME()DATETIME 数据组合成DATETIME 值。这将为您提供 5 月 5 日 07:00 的信息。

 ADDTIME(DATE('2015-05-01'), TIME('07:00:00'))

然后您将其从您当地的地理时间转换为 UTC。

CONVERT_TZ( ADDTIME(DATE('2015-05-01'), TIME('07:00:00')), 'America/New_York', 'UTC')

试试这个 MySQL 语句,你会发现America/New_York 转换正确地处理了夏令时。

select CONVERT_TZ( ADDTIME(DATE('2015-05-01'), TIME('07:00:00')), 'America/New_York', 'UTC'),
       CONVERT_TZ( ADDTIME(DATE('2015-01-01'), TIME('07:00:00')), 'America/New_York', 'UTC')

这适用于各种时区。例如,请参阅 here 以获取列表。

如果您是从头开始设计数据库,那么在同一时区记录所有时间是明智之举。事实上,将您的服务器设置为以 UTC 运行,而不是本地时间。最简单的方法是使用 MySQL 的 TIMESTAMP 数据类型:它总是在内部以 UTC 记录时间。录制时转换为本地时间,检索时转换回本地时间。它使用连接的时区设置来执行此操作。

编辑

假设您有一个包含 user_id、evdate、evtime 和 description 列的事件表。假设您还有一个包含 user_id 和 user_tz 列的用户表。然后,您可以使用这样的查询找到两个日期(UTC)之间的事件。

  SELECT u.user_name, e.description, 
         CONVERT_TZ( ADDTIME(e.evdate, e.evtime), u.user_tz, 'UTC') start
    FROM event.e
    JOIN user.u ON e.user_id = u.user_id
   WHERE CONVERT_TZ( ADDTIME(e.evdate, e.evtime), u.user_tz, 'UTC') >= '2015-03-01 00:00:00'

这假设每个用户都有一个指定的时区,并且该用户的所有日期和时间都存储在该用户指定的时区中。

【讨论】:

  • 谢谢,所以只要我存储了事件的日期和时区名称,我就不必在将其添加到数据库时转换时间,对吧?
猜你喜欢
  • 2012-04-07
  • 2016-02-06
  • 2020-01-13
  • 2017-05-12
  • 2014-11-28
  • 2017-03-02
  • 1970-01-01
  • 2012-12-03
  • 2014-08-11
相关资源
最近更新 更多