Database 使用时区支持构建unix时间戳

Database 使用时区支持构建unix时间戳,database,language-agnostic,time,timezone,Database,Language Agnostic,Time,Timezone,我有一张桌子,每一行都有一个时间戳。时间戳是unix时间戳。我想用这些数据做一些报告,这需要我按照特定的时间段对这些数据进行分组(现在,让我们只说一天:86400秒)。这可以通过设置时间戳来实现,即: mysql> set time_zone='+00:00'; Query OK, 0 rows affected (0.00 sec) mysql> select NOW(), FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP()/86400)*86400); +

我有一张桌子,每一行都有一个时间戳。时间戳是unix时间戳。我想用这些数据做一些报告,这需要我按照特定的时间段对这些数据进行分组(现在,让我们只说一天:86400秒)。这可以通过设置时间戳来实现,即:

mysql> set time_zone='+00:00';
Query OK, 0 rows affected (0.00 sec)

mysql> select NOW(), FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP()/86400)*86400);
+---------------------+----------------------------------------------------+
| NOW()               | FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP()/86400)*86400) |
+---------------------+----------------------------------------------------+
| 2013-01-17 06:06:37 | 2013-01-17 00:00:00                                |
+---------------------+----------------------------------------------------+
1 row in set (0.01 sec)
这允许我执行以下数据汇总:

select FROM_UNIXTIME(FLOOR(timestamp/86400)*86400) groupts, count(some_id) from table group by groupts order by groupts;
所有这些工作都很完美,现在我想将这些数据与其他一些报告进行比较,其中我只有特定时区的数据,比如说EST

不幸的是(很明显),地板不再起作用了:

mysql> set time_zone='-05:00';
Query OK, 0 rows affected (0.00 sec)

mysql> select NOW(), FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP()/86400)*86400);
+---------------------+----------------------------------------------------+
| NOW()               | FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP()/86400)*86400) |
+---------------------+----------------------------------------------------+
| 2013-01-17 01:10:38 | 2013-01-16 19:00:00                                |
+---------------------+----------------------------------------------------+
1 row in set (0.00 sec)
最后我想问一个问题: 有没有办法根据特定的时区确定时间戳?i、 e,地板将确保该时区中00:00-23:59的所有值都在特定组中结束


谢谢

您需要将时区偏移从UTC转换为秒;然后,在除法和乘法之前,您需要从Unix时间戳中加上或减去该偏移量,然后再将其加回来

例如:

我们可以在时区UTC-05:00(美国/东部或美国/纽约)中确定日期2012-01-17的UTC值范围:

时区偏移距UTC为-18000秒(5*3600),当然,一天有86400秒

然后,我们可以使用
bc
显示计算应为:

  • ((utc_时间+tz_偏移)/秒/秒/天)*秒/秒/天-tz_偏移
例如,我们可以使用
bc
进行计算:

$ bc
scale=0
a=1358398800
b=a+86400
c=-18000
d=86400
((a+c)/d)*d-c
1358398800
((b-1+c)/d)*d-c
1358398800
((b+c)/d)*d-c
1358485200
b
1358485200
quit
$
如您所见,美国/东部时区2012-01-17期间的时间都被归为同一组(使用极端时间值进行演示)

因此,只要您可以计算时区与UTC的偏移量(以秒为单位),格林威治子午线以西的时区为负值,以东的时区为正值,那么您就可以使用所示的计算

SELECT NOW(), FROM_UNIXTIME(FLOOR((UNIX_TIMESTAMP() + (-18000))/86400)*86400 - (-18000));
概括而言:

FLOOR((timestamp + (offset_in_seconds))/86400)*86400 - (offset_in_seconds)

其中,以秒为单位的偏移量可以是正的或负的。

您需要将时区偏移量从UTC转换为秒;然后,在除法和乘法之前,您需要从Unix时间戳中加上或减去该偏移量,然后再将其加回来

例如:

我们可以在时区UTC-05:00(美国/东部或美国/纽约)中确定日期2012-01-17的UTC值范围:

时区偏移距UTC为-18000秒(5*3600),当然,一天有86400秒

然后,我们可以使用
bc
显示计算应为:

  • ((utc_时间+tz_偏移)/秒/秒/天)*秒/秒/天-tz_偏移
例如,我们可以使用
bc
进行计算:

$ bc
scale=0
a=1358398800
b=a+86400
c=-18000
d=86400
((a+c)/d)*d-c
1358398800
((b-1+c)/d)*d-c
1358398800
((b+c)/d)*d-c
1358485200
b
1358485200
quit
$
如您所见,美国/东部时区2012-01-17期间的时间都被归为同一组(使用极端时间值进行演示)

因此,只要您可以计算时区与UTC的偏移量(以秒为单位),格林威治子午线以西的时区为负值,以东的时区为正值,那么您就可以使用所示的计算

SELECT NOW(), FROM_UNIXTIME(FLOOR((UNIX_TIMESTAMP() + (-18000))/86400)*86400 - (-18000));
概括而言:

FLOOR((timestamp + (offset_in_seconds))/86400)*86400 - (offset_in_seconds)

其中以秒为单位的偏移量可以是正的,也可以是负的。

我已经编辑了您的答案并修复了查询。实际查询应该是:FLOOR((timestamp+(offset_in_seconds))/86400)*86400-(offset_in_seconds)。谢谢你的回答!我已经编辑了您的答案并修复了问题。实际查询应该是:FLOOR((timestamp+(offset_in_seconds))/86400)*86400-(offset_in_seconds)。谢谢你的回答!