我使用Laravel / PHP / MySQL并以UTC格式存储所有日期和时间。
用户可以选择时区(例如Eastern),输入日期和时间,日期和时间将在存储之前转换为UTC。在检索时,它将被转换为用户选择的时区。
我的问题是如何从考虑时区的一系列记录中获得平均时间(最好是在数据库查询中)?以下问题解决了PHP中的平均时间,但不是时区问题。
以下是我正在做的事情:
SEC_TO_TIME( AVG( TIME_TO_SEC( TIME(flights.departed_at) ) ) ) ) AS average_time
除了在观察它的区域中跨越夏令时/标准时间的记录之外,这是有效的。
例如:您可能拥有一个用户在EDT 2015-08-18 11:00:00
输入的UTC日期时间为2015-08-18 07:00:00
的记录。然后,您在2015-11-10 12:00:00
的EST中由用户输入了UTC日期时间为2015-11-10 07:00:00
的第二条记录。如果您尝试计算平均时间,则应该等同于07:00:00
,但结果为07:30:00
。
任何想法如何克服这一点?我接近这一切都错了吗?
提前致谢。
答案 0 :(得分:1)
简而言之,您的代码正常运行。一旦日期为UTC,您必须重新计算是否在夏令时期间输入(1),(2)实际观察夏令时的人,以及(3)在某个地方识别夏令时。
我真的只想到一种方法来解决这个问题。
保存数据时添加某种标志以将时间戳标记为DST。您可以使用此标志来调整小时差异。如何生成此标志取决于您。
答案 1 :(得分:0)
如果您将所有时间都存储在Z中,并且您的MySQL数据库具有timezones loaded correctly,则可以使用zoneinfo时区名称来检索当地时间。例如,
SELECT CONVERT_TZ('2015-08-01 11:00', 'UTC', 'America/New_York'),
CONVERT_TZ('2015-12-01 12:00', 'UTC', 'America/New_York')
产量
2015-08-01 07:00 2015-12-01 07:00
关键是,zoneinfo数据库知道每个日期时间值使用夏令时或标准时间。它不使用当前偏移量,它使用对相关日期有效的偏移量。
因此,您可以使用如下表达式检索当地时间的时间:
TIME(CONVERT_TZ(utc_time_column, 'UTC', 'America/New_York'))
然后,你按照通常的方式平均那些时间。