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

Mysql 如何按日期分组,考虑时区和DST?,mysql,datetime,timezone,Mysql,Datetime,Timezone,我的数据库中存储了大量事件。每个事件都有一个开始时间,以UTC格式存储为DATETIME。每个用户都可以选择自己的时区 我想显示一个日历,它只显示一个月中每天的事件数。我不能按日期分组(start_dt),因为用户的一天[不一定]在UTC的00:00:00开始。此外,用户的时区可能在月中旬有一个DST交换机。 那么,我唯一的选择是获取给定月份的每个事件,然后使用我的服务器端语言对它们进行分组和计数吗?您可以立即切换到用户tz: SET @@session.time_zone = "+05:0

我的数据库中存储了大量事件。每个事件都有一个开始时间,以UTC格式存储为
DATETIME
。每个用户都可以选择自己的时区

我想显示一个日历,它只显示一个月中每天的事件数。我不能
按日期分组(start_dt)
,因为用户的一天[不一定]在UTC的00:00:00开始。此外,用户的时区可能在月中旬有一个DST交换机。
那么,我唯一的选择是获取给定月份的每个事件,然后使用我的服务器端语言对它们进行分组和计数吗?

您可以立即切换到用户tz:

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

刚刚发现:

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

当前时区设置不影响UTC_TIMESTAMP()等函数显示的值或日期、时间或日期时间列中的值。这些数据类型中的值也不会存储在UTC中;时区仅在从时间戳值转换时适用。如果希望对日期、时间或日期时间值使用特定于区域设置的算术,请将它们转换为UTC,执行算术,然后再转换回

幸运的是,这确实意味着日期/时间函数应该使用时区支持,但只能在
TIMESTAMP
列上使用。在
时间戳
列中,日期/时间函数应该能够考虑
@@session.timeZone
,您可以根据需要更改它以获得不同的时区

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

您可以尝试一下

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

请注意,您需要这样做才能工作。

更改时区实际上不会影响我的
DATETIME
字段,是吗?不幸的是,不会。来自MySQL文档:“当前时区设置不影响UTC_TIMESTAMP()等函数显示的值或DATE、TIME或DATETIME列中的值。这些数据类型中的值也不是存储在UTC中的值;时区仅在从时间戳值转换时适用。如果要为日期、时间或DATETIME值使用特定于区域设置的算术,请将其转换为UTC,执行算术,然后再转换回。“否!只需尝试设置@session.time_zone=“+03:00”;从dual中选择now()它不会改变你的时钟…@AxelAmthor那是个问题。按
DATE()
分组将与我没有设置时区完全相同。据我所知,让MySQL执行区域设置感知操作的唯一方法是使用
TIMESTAMP
列执行所有操作;然后会话时区将用于分组等。您只需记住tzdata不是一成不变的,一旦您将一些日期转换为时间戳,您就不必在时区规则更改后将其正确返回。或者使用数字偏移量作为
CONVERT_TZ()
()的第三个参数,因此,它不需要时区表,例如,
CONVERT_TZ('2004-01-01 12:00:00','UTC','+10:00')@RandomSeed这是DST的问题。月初的偏移量可能与月底的偏移量不同,但您在示例中没有犯什么错误。它应该是:
CONVERT_TZ('2004-01-01 12:00:00','+00:00','+10:00')
因为使用
UTC
而不是
+00:00
仍然会导致
NULL