I have a table, where each row has a timestamp. The timestamp is a unix timestamp. I’d like to do some reporting using this data, which requires me to group this data by a specific period (for now, let’s just say day: so 86400 seconds). This can be achieved by flooring the timestamp, i.e:
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)
This allows me to do the following data rollup:
select FROM_UNIXTIME(FLOOR(timestamp/86400)*86400) groupts, count(some_id) from table group by groupts order by groupts;
All of this works perfectly, now I’d like to compare the data with some other report, where I only have the data in a specific timezone, let’s say its EST.
Unfortunately (and obviously), flooring doesn’t work anymore:
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)
Which finally brings me to my question:
Is there any way to floor the timestamp based on a specific timezone? i.e, flooring will ensure all values from 00:00-23:59 in that timezone end up in a specific group?
Thanks!
You need to convert the time zone offset from UTC into seconds; you then need to add or subtract that offset from the Unix timestamp before dividing and multiplying, and then add it back again.
For example:
We can establish the range of UTC values for the date 2012-01-17 in timezone UTC-05:00 (US/Eastern, or America/New_York):
The time zone offset is -18,000 seconds from UTC (5 * 3,600), and there are 86,400 seconds in a day, of course.
We can then show with
bcthat the computation should be:For example, we can use
bcto do the calculation:As you can see, the times during 2012-01-17 in the US/Eastern time zone are all grouped into the same group (demonstrated using the extreme time values).
So, as long as you can compute the offset of the time zone from UTC in seconds, with negative values for time zones west of the Greenwich Meridian and positive values for time zones east of it, then you can use the calculation shown.
To generalize:
Where offset_in_seconds can be positive or negative.