如何选择昨天从午夜到午夜的所有记录,查找特定位置的时区(所有时间戳都在UTC,地点已命名为时区 - 例如美国/温哥华)?
请注意,我并未询问如何将日期和时间转换为其他时区。我要问的是如何[最佳]本地化日期范围比较。
答案 0 :(得分:0)
假设您的MySQL数据库会话的时区是UTC(即time_zone =' +00:00')...
假设你想对所有行使用相同的时区(即根据行的内容没有不同的时区......
取值"午夜"在用户指定的时区中,并将其转换为UTC。例如2016-04-16 00:00 CST6CDT(即America / Chicago)转换为2016-04-16 05:00 UTC。
假设您的表列名为utc_timestamp_col,并且数据类型为TIMESTAMP,您的查询看起来应如下所示:
SELECT ...
FROM mytable t
WHERE t.utc_timestamp_col >= '2016-04-16 05:00' + INTERVAL -1 DAY
AND t.utc_timestamp_col < '2016-04-16 05:00' + INTERVAL 0 DAY
如果已填充MySQL时区表,则可以使用MySQL支持命名时区。 http://dev.mysql.com/doc/refman/5.7/en/time-zone-support.html
您可以构建一个表达式,让您以前的&#34;午夜&#34;在一个指定的时区。
以下是演示查询:
e.g。
SELECT @@session.time_zone AS `time_zone`
, NOW() AS `now_utc`
, CONVERT_TZ(NOW(),'UTC','CST6CDT') AS `now_CST6CDT`
, DATE(CONVERT_TZ(NOW(),'UTC','CST6CDT')) AS `midnight_CST6CDT`
, CONVERT_TZ(DATE(CONVERT_TZ(NOW(),'UTC','CST6CDT')),'CST6CDT','UTC')
AS midnight_CST6CDT_utc
返回:
time_zone now_utc now_CST6CDT midnight_CST6CDT midnight_CST6CDT_utc
--------- ------------------- ------------------- ---------------- --------------------
UTC 2016-04-17 01:53:31 2016-04-16 20:53:31 2016-04-16 2016-04-16 05:00:00
使用名为&#39; America / Chicago&#39;
的时区展示同样的事情SELECT @@session.time_zone AS `time_zone`
, NOW() AS now_utc
, CONVERT_TZ(NOW(),'UTC','America/Chicago') AS `now_America/Chicago`
, DATE(CONVERT_TZ(NOW(),'UTC','America/Chicago')) AS `midnight_America/Chicago`
, CONVERT_TZ(DATE(CONVERT_TZ(NOW(),'UTC','America/Chicago')),'America/Chicago','UTC')
AS `midnight_America/Chicago_utc`
返回相同的结果:
time_zone now_utc now_America/Chicago midnight_America/Chicago midnight_America/Chicago_utc
--------- ------------------- ------------------- ------------------------ ----------------------------
UTC 2016-04-17 01:57:19 2016-04-16 20:57:19 2016-04-16 2016-04-16 05:00:00
<强>后续强>
如果我需要在查询中进行这种时区转换,我会使用内联视图从相当复杂的表达式返回值,以使外部语句更简单。例如,内联视图别名为&#34; d&#34;将值返回为名为&#34; dt&#34;的列,可以在外部查询中引用。
由于该内联视图只返回一行,我们可以使用JOIN
到mytable而不复制任何行。我们可以将谓词从WHERE子句移动到ON子句。 e.g。
SELECT ...
FROM ( SELECT CONVERT_TZ(DATE(CONVERT_TZ(NOW(),'UTC','CST6CDT')),'CST6CDT','UTC') AS dt
) d
JOIN mytable t
ON t.utc_timestamp_col >= d.dt + INTERVAL -1 DAY
AND t.utc_timestamp_col < d.dt + INTERVAL 0 DAY