我有一个用户可以存储和事件的表格。事件的开始时间存储在列中,列字段为time
。在夏令时期间,我所处的位置,以小时为单位的偏移量为-5
,因此如果用户存储从12:00pm
开始的事件,则它将作为17:00:00
存储在数据库中。如果用户在没有夏令时的情况下创建具有完全相同的开始时间的事件,则时区偏移量将为-4
,并且它将作为16:00:00
存储在数据库中。
如果用户选择从中午12:00开始的所有活动及其夏令时,我将使用javascript(在本例中为-5)获取用户时区偏移并相应地创建查询{{1} }。问题是当夏令时没有WHERE startTime > 17:00:00
的开始时间时创建的所有事件,因为偏移量为16:00:00
而不是-4
因此它们不会地选择。
解决这个问题的方法是什么?我存储事件的startTime的方法是完全错误的吗?
答案 0 :(得分:1)
如果您有DATE
和TIME
值,并且您知道记录这些日期和时间时使用的地理时区,则可以使用CONVERT_TZ()
从中检索UTC时间当地时间数据。
首先,您使用ADDTIME()
将DATE
和TIME
数据合并为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'
这假设每个用户都有一个指定的时区,并且该用户的所有日期和时间都存储在该用户指定的时区中。