我有一个表,每行都有一个时间戳。时间戳是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)
这终于让我想到了我的问题: 有没有办法根据特定时区设置时间戳?即,地板将确保该时区中00:00-23:59的所有值最终都在特定组中?
谢谢!
答案 0 :(得分:0)
您需要将时区偏移量从UTC转换为秒;然后,您需要在划分和乘法之前在Unix时间戳中添加或减去该偏移量,然后再将其重新添加。
例如:
我们可以按时区UTC-05:00(美国/东部或美国/纽约)确定日期2012-01-17的UTC值范围:
$ timestamp -Z -z -05:00 1358398800 1358485200
1358398800 = Thu Jan 17 00:00:00 2013 -05:00
1358485200 = Fri Jan 18 00:00:00 2013 -05:00
$ timestamp -Z -z 00:00 1358398800 1358485200
1358398800 = Thu Jan 17 05:00:00 2013 +00:00
1358485200 = Fri Jan 18 05:00:00 2013 +00:00
$
时区偏离UTC(5 * 3,600)为-18,000秒,当然一天有86,400秒。
然后我们可以用bc
显示计算应该是:
例如,我们可以使用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)
其中offset_in_seconds可以是正数或负数。