LoginSignup
0
0

More than 5 years have passed since last update.

日付またぎの境界をtimezoneをずらして検索する

Last updated at Posted at 2018-03-06

日次データの区切りが 前日の AM 5:00 から 当日の AM 5:00 まで

みたいなケースってよくあるじゃないですか。

とりあえずテストデータ投入

bash
{
    cat <<-EOD
set timezone to 'Asia/Tokyo';

DROP TABLE IF EXISTS hoge;
CREATE TABLE hoge (
    i int,
    d timestamp
);
EOD

    echo 'INSERT INTO hoge VALUES'
    for x in {-48..0}; do
        echo "($x, CURRENT_TIMESTAMP + interval '$x hour')"
    done | paste -s -d ','
    echo ";"

    echo "SELECT * FROM hoge;"
} | psql

で、こんな感じ。

result
  i  |             d
-----+----------------------------
 -48 | 2018-03-04 16:52:46.826483
 -47 | 2018-03-04 17:52:46.826483
 -46 | 2018-03-04 18:52:46.826483
 -45 | 2018-03-04 19:52:46.826483
 -44 | 2018-03-04 20:52:46.826483
 -43 | 2018-03-04 21:52:46.826483
 -42 | 2018-03-04 22:52:46.826483
 -41 | 2018-03-04 23:52:46.826483
 -40 | 2018-03-05 00:52:46.826483
 -39 | 2018-03-05 01:52:46.826483
 -38 | 2018-03-05 02:52:46.826483
 -37 | 2018-03-05 03:52:46.826483
 -36 | 2018-03-05 04:52:46.826483
 -35 | 2018-03-05 05:52:46.826483
 -34 | 2018-03-05 06:52:46.826483
 -33 | 2018-03-05 07:52:46.826483
 -32 | 2018-03-05 08:52:46.826483
 -31 | 2018-03-05 09:52:46.826483
 -30 | 2018-03-05 10:52:46.826483
 -29 | 2018-03-05 11:52:46.826483
 -28 | 2018-03-05 12:52:46.826483
 -27 | 2018-03-05 13:52:46.826483
 -26 | 2018-03-05 14:52:46.826483
 -25 | 2018-03-05 15:52:46.826483
 -24 | 2018-03-05 16:52:46.826483
 -23 | 2018-03-05 17:52:46.826483
 -22 | 2018-03-05 18:52:46.826483
 -21 | 2018-03-05 19:52:46.826483
 -20 | 2018-03-05 20:52:46.826483
 -19 | 2018-03-05 21:52:46.826483
 -18 | 2018-03-05 22:52:46.826483
 -17 | 2018-03-05 23:52:46.826483
 -16 | 2018-03-06 00:52:46.826483
 -15 | 2018-03-06 01:52:46.826483
 -14 | 2018-03-06 02:52:46.826483
 -13 | 2018-03-06 03:52:46.826483
 -12 | 2018-03-06 04:52:46.826483
 -11 | 2018-03-06 05:52:46.826483
 -10 | 2018-03-06 06:52:46.826483
  -9 | 2018-03-06 07:52:46.826483
  -8 | 2018-03-06 08:52:46.826483
  -7 | 2018-03-06 09:52:46.826483
  -6 | 2018-03-06 10:52:46.826483
  -5 | 2018-03-06 11:52:46.826483
  -4 | 2018-03-06 12:52:46.826483
  -3 | 2018-03-06 13:52:46.826483
  -2 | 2018-03-06 14:52:46.826483
  -1 | 2018-03-06 15:52:46.826483
   0 | 2018-03-06 16:52:46.826483
(49 rows)

真面目にやると

で、ここから 2018-03-05 分として
2018-03-05 05:00:00 から 2018-03-06 05:00:00 までの要件で検索しようとすると、

psql
\set target_date '2018-03-05'

SET timezone TO 'Asia/Tokyo';

SELECT
  i
  , d
FROM hoge
WHERE
  (:'target_date'::DATE || ' 05:00:00')::TIMESTAMP <= d
  AND d < ((:'target_date'::DATE + interval '+1 day')::DATE || ' 05:00:00')::TIMESTAMP
;

みたいな感じで頑張るわけで、積み重なってくるとけっこうつらい。

result
  i  |             d
-----+----------------------------
 -35 | 2018-03-05 05:52:46.826483
 -34 | 2018-03-05 06:52:46.826483
 -33 | 2018-03-05 07:52:46.826483
 -32 | 2018-03-05 08:52:46.826483
 -31 | 2018-03-05 09:52:46.826483
 -30 | 2018-03-05 10:52:46.826483
 -29 | 2018-03-05 11:52:46.826483
 -28 | 2018-03-05 12:52:46.826483
 -27 | 2018-03-05 13:52:46.826483
 -26 | 2018-03-05 14:52:46.826483
 -25 | 2018-03-05 15:52:46.826483
 -24 | 2018-03-05 16:52:46.826483
 -23 | 2018-03-05 17:52:46.826483
 -22 | 2018-03-05 18:52:46.826483
 -21 | 2018-03-05 19:52:46.826483
 -20 | 2018-03-05 20:52:46.826483
 -19 | 2018-03-05 21:52:46.826483
 -18 | 2018-03-05 22:52:46.826483
 -17 | 2018-03-05 23:52:46.826483
 -16 | 2018-03-06 00:52:46.826483
 -15 | 2018-03-06 01:52:46.826483
 -14 | 2018-03-06 02:52:46.826483
 -13 | 2018-03-06 03:52:46.826483
 -12 | 2018-03-06 04:52:46.826483
(24 rows)

そこで

postgresql の timestamp 型はタイムゾーン持ってない1ので、
検索対象のカラムのタイムゾーンちょっとずらして検索かけてやると

psql
\set target_date '2018-03-05'

SET timezone TO 'Asia/Tokyo';

SELECT
  i
  , d
  , (d AT TIME ZONE 'Etc/GMT-14')::DATE AS boundary_AM5_date
FROM hoge
WHERE
  (d AT TIME ZONE 'Etc/GMT-14')::DATE = :'target_date'::DATE
;

範囲検索使わなくても検索できる。

result
  i  |             d              | boundary_am5_date
-----+----------------------------+-------------------
 -35 | 2018-03-05 05:52:46.826483 | 2018-03-05
 -34 | 2018-03-05 06:52:46.826483 | 2018-03-05
 -33 | 2018-03-05 07:52:46.826483 | 2018-03-05
 -32 | 2018-03-05 08:52:46.826483 | 2018-03-05
 -31 | 2018-03-05 09:52:46.826483 | 2018-03-05
 -30 | 2018-03-05 10:52:46.826483 | 2018-03-05
 -29 | 2018-03-05 11:52:46.826483 | 2018-03-05
 -28 | 2018-03-05 12:52:46.826483 | 2018-03-05
 -27 | 2018-03-05 13:52:46.826483 | 2018-03-05
 -26 | 2018-03-05 14:52:46.826483 | 2018-03-05
 -25 | 2018-03-05 15:52:46.826483 | 2018-03-05
 -24 | 2018-03-05 16:52:46.826483 | 2018-03-05
 -23 | 2018-03-05 17:52:46.826483 | 2018-03-05
 -22 | 2018-03-05 18:52:46.826483 | 2018-03-05
 -21 | 2018-03-05 19:52:46.826483 | 2018-03-05
 -20 | 2018-03-05 20:52:46.826483 | 2018-03-05
 -19 | 2018-03-05 21:52:46.826483 | 2018-03-05
 -18 | 2018-03-05 22:52:46.826483 | 2018-03-05
 -17 | 2018-03-05 23:52:46.826483 | 2018-03-05
 -16 | 2018-03-06 00:52:46.826483 | 2018-03-05
 -15 | 2018-03-06 01:52:46.826483 | 2018-03-05
 -14 | 2018-03-06 02:52:46.826483 | 2018-03-05
 -13 | 2018-03-06 03:52:46.826483 | 2018-03-05
 -12 | 2018-03-06 04:52:46.826483 | 2018-03-05
(24 rows)

っていう話。

Amazon Redshift でもたぶん使える、と思う。

なんでこれでOKか

こういう対応。

Asia/Tokyo UTC Etc/GMT-14
2018-03-06 05:52:46 2018-03-06 14:52:46 2018-03-06 00:52:46
  • Asia/Tokyo+09:00

なので、

  • Etc/GMT-14+14:00(ここ名前に反して - じゃなくて + なのがややこしいので注意)

を指定してやると、日本時間から-5時間ずれてちょうどいい感じになる。


  1. タイムゾーン持ってる timestamptz 型っていうのが別にある 

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0