LoginSignup
7
2

More than 5 years have passed since last update.

JetBrains製EditorでPostgreSQLに接続するときのタイムゾーンについて 

Posted at

タイムゾーンが設定値と異なる

PostgreSQL側でタイムゾーンをAsia/Tokyoで指定したのに、InteliJのようなJetBrains製のエディターから接続した時にUTCに変わってしまうことがありました。参照するだけであればそこまで問題ではないですが、そこから現在時刻を挿入するようなことがあれば想定と異なるデータになるため問題になります。

このまま使うのが怖かったので調べたところ、InteliJでタイムゾーンを明示的に指定する方法を見つけたので調査結果と解決策についてまとめます。

前提知識と準備

PostgresSQLのタイムゾーン

PostgresSQLのタイムゾーンはpostgresql.confに設定します。

timezone = 'Asia/Tokyo'

※AWSのRDSではクラウドパラメータという機能を使って設定することができるので別の設定方法があります。

下記のクエリを投げると現在のタイムゾーンを確認できます。

show timezone;

クエリでタイムゾーンを変更する方法

クエリでデータベース単位で変更する方法です。検証で使うので先に書いておきます。

ALTER DATABASE DB_NAME SET timezone TO 'Asia/Tokyo'

セッション単位で変更する時(接続を切れば元に戻る)

SET timezone TO 'Asia/Tokyo'

タイムゾーンがAsia/TokyoなPostgreSQLを立ち上げる

ローカルにPostgreSQLのdockerコンテナを立てます。

version: "3"
services:
  postgres:
    image: postgres:9.6
    container_name: "postgres_practice"
    ports:
      - 5432:5432
    environment:
      - POSTGRES_USER=postgres_practice
      - POSTGRES_PASSWORD=postgres_practice
      - POSTGRES_DB=practice
    user: root

立ち上げます。

docker-compose up

タイムゾーンを確認するとUTCになっています。

docker exec -it postgres_practice psql -U postgres_practice -W -d practice -c "show timezone"
Password for user postgres_practice:
 TimeZone
----------
 UTC
(1 row)

デフォルトではUTCになっているのでAsia/Tokyoに変更します。

docker exec -it postgres_practice sed -i 's/UTC/Asia\/Tokyo/g' /var/lib/postgresql/data/postgresql.conf

再起動します。

docker-compose restart

これでタイムゾーンがAsia/TokyoなPostgreSQLが立ち上がります。

docker exec -it postgres_practice psql -U postgres_practice -W -d practice -c "show timezone"                                                                2824ms  月  4/15 02:37:48 2019
Password for user postgres_practice:
  TimeZone
------------
 Asia/Tokyo
(1 row)

JetBrains製のEditorで確認

しっかりAsia/TokyoなPostgresが立ち上がったところで、JetBrains製のエディターで確認してみます。

下記のような設定で接続します。

スクリーンショット 2019-04-15 3.28.19.png

タイムゾーンを確認。

スクリーンショット 2019-04-15 2.46.55.png

なんでやねん。
しっかりUTCで上書きされてました。

データベース単位でタイムゾーン変更クエリを流してみます。

ALTER DATABASE practice SET timezone TO 'Asia/Tokyo'
SHOW timezone

スクリーンショット 2019-04-15 2.50.41.png

変化なし。

次はセッション単位で変更してみます。

SET timezone TO 'Asia/Tokyo';
SHOW timezone

スクリーンショット 2019-04-15 2.51.50.png

変わりました。ただしこれは再接続するとまたUTCに戻ります。

つまりセッション単位で何かしらエディター側で設定が上書きされていることがわかります。
でも毎回打つのはいやです。

linuxのタイムゾーンを変えてみる

コンテナの中のタイムゾーンを変えたら変化があるかもしれないと思って試してみました。

現在値の確認。

docker exec -it postgres_practice ls -l /etc/localtime                                                                                                                月  4/15 02:56:35 2019
lrwxrwxrwx 1 root root 27 Mar 26 12:00 /etc/localtime -> /usr/share/zoneinfo/Etc/UTC

更新。

docker exec -it postgres_practice ln -sf  /usr/share/zoneinfo/Asia/Tokyo /etc/localtime

確認。

docker exec -it postgres_practice date
Mon Apr 15 02:57:25 JST 2019

PostgreSQLに繋いでエディターで確認。
スクリーンショット 2019-04-15 3.15.13.png

変わらない...

下記コマンドを実施して効果なし。

docker exec -it postgres_practice /bin/bash
root:/# echo "Asia/Tokyo" > /etc/timezone
root:/# dpkg-reconfigure -f noninteractive tzdata

Current default time zone: 'Asia/Tokyo'
Local time is now:      Mon Apr 15 03:02:37 JST 2019.
Universal Time is now:  Sun Apr 14 18:02:37 UTC 2019.

接続時にオプションを指定する

DataGripのFAQにこんな記述がありました。

DataGrip shows time in local time zone, I want it to be shown in UTC, what should I do?
Go to Advanced tab of datasource and put -Duser.timezone=UTC into VM options field.

local time zoneになってしまうから明示的にオプションでタイムゾーンを指定しろと書いてます。
上記の手順で変わらない理由はよくわかりませんが試してみます。

スクリーンショット 2019-04-15 3.32.53.png

これで確認してみると変わりました。
スクリーンショット 2019-04-15 3.33.49.png

まとめ

調査した結果、タイムゾーンを指定するためには

  • SET timezone TO 'Asia/Tokyo' を実行する
  • オプションで指定する

の2パターンあることがわかりました。
エディターで指定することで設定後は意識することなくAsia/Tokyoで接続できるようになるので、この対応をしておくと基本的には安心だと思います。

具体的な原因は分かり次第追記しようと思います。

7
2
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
7
2