mysql - 当日期存储为 unix 时间戳时,如何计算 1967 年 9 月 3 日美国东部时间出生的人数?

标签 mysql date

假设我数据库中的某人出生于 -73440000 unix 时间。这意味着他出生于 04-Sep-1967 UTC 但 03-Sep-1967 EDT。我如何计算一年中每一天在美国东部时间出生的人数?


马上,你会发现

SELECT FROM_UNIXTIME(-73440000)
-- returns NULL

返回 NULL。 MySQL 无法处理负的 unix 时间戳。

好吧,我们可以解决这个问题:

select date_add('1970-01-01', interval -73440000 second)
-- returns 1967-09-04 00:00:00

产生 1967-09-04 00:00:00,这是他在 UTC 中的生日。

我们可以尝试将其转换为 EDT(多伦多时间):

select convert_tz('1967-09-04 00:00:00','UTC','America/Toronto')
-- returns 1967-09-04 00:00:00, but should be 1967-09-03 20:00:00

但事实证明,CONVERT_TZ 也不适用于 1970 年之前的日期。

(我有 installed the timezones already 并且它确实在 1970 年到 2038 之间的日期工作)

所以现在我卡住了。我需要将 unix 时间戳转换为 MySQL DATE,以便我可以对其进行 GROUP BY 然后对其进行计数。我能想到的唯一其他选择是将数据库中的 记录作为 unix 时间戳返回,并使用另一种语言进行转换并计算它们,但如果有数百万条,那可能会有点荒谬记录。

注意您也无法计算 EDT 和 UTC 之间的小时偏移量,因为它会在全年发生变化(夏令时)。

最佳答案

您可以手动进行转换;如果您已经将区域数据加载到 MySQL 中,那么您已经获得了可追溯到 1918 年的数据。让我们看一下列表:

SET @timezone = "America/Toronto";
SELECT FROM_UNIXTIME(0) + INTERVAL Transition_Time SECOND AS change_time, Offset, Abbreviation
FROM mysql.time_zone_transition t
LEFT JOIN mysql.time_zone_transition_type tt ON (
    t.Time_zone_id = tt.Time_zone_id AND
    t.Transition_type_id = tt.Transition_type_id
)
LEFT JOIN mysql.time_zone_name n ON (
    t.Time_zone_id = n.Time_zone_id
)
WHERE n.Name = @timezone
    AND Transition_time < 0
ORDER BY change_time ASC;

修改您的样本日期,我们可以提取:

SET @timezone = "America/Toronto";
SET @birthday = -73440000;

SELECT ('1970-01-01 00:00:00' + INTERVAL @birthday SECOND) + INTERVAL Offset SECOND AS offsetDate
FROM mysql.time_zone_transition t
LEFT JOIN mysql.time_zone_transition_type tt ON (
    t.Time_zone_id = tt.Time_zone_id AND
    t.Transition_type_id = tt.Transition_type_id
)
LEFT JOIN mysql.time_zone_name n ON (
    t.Time_zone_id = n.Time_zone_id
)
WHERE n.Name = @timezone
    AND Transition_time < @birthday
ORDER BY Transition_time DESC
LIMIT 1;

由于它选择日期之前的最近转换,因此它不会返回第一个转换之前的日期的记录。这应该作为您在 terra incognita 中的指示器,并且必须弥补您自己的偏移量。

如果您想使用第一个过渡时间作为后备,您可以删除 Transition_time < @birthday来自 WHERE子句并将其添加到 ORDER BY子句,正如您在评论中所建议的那样。

关于mysql - 当日期存储为 unix 时间戳时,如何计算 1967 年 9 月 3 日美国东部时间出生的人数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34933993/

相关文章:

php - PHP Mysql-使用分组依据的交易

javascript - 如何从用户本地时间中减去 2 小时?

jquery - 星期几和时刻 js

java - 从字符串java中提取日期

Java 日历/日期 : AM and PM not setting correctly

mysql - 在 Apache Phoenix API 上运行查询时出现异常

mysql - cakephp + phpunit + gitlab 持续集成

c# - 在 DataGridView C# 中复制项目

php - 按关联项搜索的 SQL

java - java中的哪种日期模式可以产生这个日期结果? (秒后七位数字)