MySQL的;使用位置的时区从昨天(午夜到午夜)选择所有记录

时间:2016-04-17 00:23:10

标签: mysql timezone

如何选择昨天从午夜到午夜的所有记录,查找特定位置的时区(所有时间戳都在UTC,地点已命名为时区 - 例如美国/温哥华)?

请注意,我并未询问如何将日期和时间转换为其他时区。我要问的是如何[最佳]本地化日期范围比较。

1 个答案:

答案 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;在一个指定的时区。

以下是演示查询:

  • 验证会话time_zone是UTC
  • 以UTC格式返回当前日期和时间
  • 转换为当地时区CST6CDT
  • 截断到午夜
  • 转换回UTC

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