如何按日期分组,考虑时区和 DST?

How to group by date, accounting for timezones and DST?

我的数据库中存储了一堆事件。每个事件都有一个开始时间,在 UTC 中存储为 DATETIME。每个用户可以选择 his/her 自己的时区。

我想显示一个日历,它只显示一个月中每一天的事件数。我不能 GROUP BY DATE(start_dt) 因为用户的一天并不 [一定] 从 00:00:00 UTC 开始。此外,用户的时区可能在月中有 DST 切换。

然后我唯一的选择是获取给定月份的每个事件,然后使用我的服务器端语言对它们进行分组和计数吗?

你可以中间切换到用户tz:

  SET @@session.time_zone = "+05:00"; 
  select ... from .. group by MONTH(datefield);
  SET @@session.time_zone = @@global.time_zone;

刚刚找到:How do I set the time zone of MySQL?

不幸的是 DATETIME 列存储时没有时区信息:

The current time zone setting does not affect values displayed by functions such as UTC_TIMESTAMP() or values in DATE, TIME, or DATETIME columns. Nor are values in those data types stored in UTC; the time zone applies for them only when converting from TIMESTAMP values. If you want locale-specific arithmetic for DATE, TIME, or DATETIME values, convert them to UTC, perform the arithmetic, and then convert back. [MySQL Docs]

幸运的是,这确实意味着 date/time 函数应该支持时区,但仅适用于 TIMESTAMP 列。一旦进入 TIMESTAMP 列,date/time 函数应该能够考虑 @@session.time_zone,您可以根据需要更改它以获得不同的时区。

因此,您的选择是保留包含 DATETIME 列的表格,并自己进行所有分组,或者将这些列转换为 TIMESTAMP 并让 MySQL 执行 - 但是如果这些列已经处于不同且不一致的时区,那么您的工作就完成了...

你可以试试

SELECT ... FROM ... GROUP BY DATE(CONVERT_TZ(start_dt,'UTC','America/Vancouver'))

请注意,您需要 load the timezone data into MySQL 才能生效。