1

各行にタイムスタンプがあるテーブルがあります。タイムスタンプはUNIXタイムスタンプです。このデータを使用してレポートを作成したいのですが、このデータを特定の期間でグループ化する必要があります(今のところ、1日としましょう: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のすべての値が特定のグループに含まれるようにしますか?

ありがとう!

4

1 に答える 1

1

UTCからのタイムゾーンオフセットを秒に変換する必要があります。次に、除算と乗算の前に、Unixタイムスタンプからそのオフセットを加算または減算してから、再度加算する必要があります。

例えば:

タイムゾーンUTC-05:00(US / Eastern、またはAmerica / New_York)で日付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から-18,000秒(5 * 3,600)であり、もちろん1日は86,400秒です。

bc次に、計算が次のようになることを示すことができます。

  • ((utc_time + tz_offset)/ secs_per_day)* secs_per_day-tz_offset

たとえば、次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は正または負になります。

于 2013-01-17T06:50:23.913 に答える