質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
86.12%
Elixir

Elixirは、並列処理や関数型に特化した、Erlang VM (BEAM) 上で動作する汎用プログラミング言語です。分散システム、耐障害性、ソフトリアルタイムシステムなどの機能を持ちます。

解決済

PostgreSQL + Ecto + Timex でタイムゾーン付き日時情報の扱い方

退会済みユーザー

退会済みユーザー

総合スコア0

Elixir

Elixirは、並列処理や関数型に特化した、Erlang VM (BEAM) 上で動作する汎用プログラミング言語です。分散システム、耐障害性、ソフトリアルタイムシステムなどの機能を持ちます。

3回答

0リアクション

0クリップ

3713閲覧

投稿2017/06/02 04:48

編集2017/06/04 04:16

###前提・実現したいこと

Ecto + Timex を使って、PostgreSQL の timestamp with timezone を扱いたいんですが、Model で持っている日時とデータベースに保存される時間がずれてしまうので、理由と対処法を知りたいです。

もっと別の方法があるよ、とかでもいいです。

参考

↑を読むと、カスタム複合タイプ datetimetz つくって対処するといいよって書いてある。

###発生している問題・エラーメッセージ

インタラクションに従って、データベースに datetimetz 型をつくって、Elixir からはTimex.Ecto.DateTimeWithTimezone 型の変数を入れられるようにしました。

sql

CREATE TYPE datetimetz AS ( dt timestamptz, tz varchar );

Timex.Ecto.DateTimeWithTimezone な変数の中身をダンプすると以下のようになっています。

elixir

IO.inspect model.inserted_at # {{{2017, 6, 2}, {11, 41, 57, 93698}}, "Asia/Tokyo"}

データベースには以下のように登録されています。

sql

("2017-06-02 20:41:57.093698+09",Asia/Tokyo)

9時間ずれている。。実際の時刻は上の方です(今日の午前11時に実行しました)。

###該当のソースコード

migrationファイル

elixir

def change do create table(:messages) do add :message, :text add :inserted_at, :datetimetz end end

モデルクラス

elixir

schema "messages" do field :message, :string field :inserted_at, Timex.Ecto.DateTimeWithTimezone end

インサート

elixir

changeset = Message.changeset(%Message{}, %{message: message, inserted_at: Timex.now("Asia/Tokyo")}) Repo.insert(changeset)

###試したこと

すみません、何を試せばいいのかすら思いつかず。。

Ectoのコード読んだくらいです(でもよく分からなかった。。)

2017-06-04 13:00 追記

@mhashi さんのコメントにもあるように、インサートの際に UTC で入れないとダメなようです。
そもそも PostgreSQL の timestamp with timezone はタイムスタンプを UTC で持っており、それを、必要に応じて変換してから出力しているみたいなので、そこに JST の日時を入れてしまうと二重に +9 されてしまうようです。

たどり着いたコードとしては、
Ecto.Adapters.Postgres.Timestamp.encode/1 の中で

elixir

:calendar.datetime_to_gregorian_seconds({{2017,6,4},{13,0,0}})

のようにして秒に変換しているのですが、当然ながらここではタイムゾーンは考慮されてないです。このタプルは、単純に Timex.Ecto.DateTimeWithTimezone の値 {{{2017,6,4},{13,0,0}}, "Asia/Tokyo"} のタイムスタンプ部分を取ってきているにすぎません。

2017-06-04 13:00 追記ここまで

###補足情報(言語/FW/ツール等のバージョンなど)

Elixir 1.4
ecto 2.1
timex 3.1
timex_ecto 3.1

以下のような質問にはリアクションをつけましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

リアクションが多い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
86.12%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

Elixir

Elixirは、並列処理や関数型に特化した、Erlang VM (BEAM) 上で動作する汎用プログラミング言語です。分散システム、耐障害性、ソフトリアルタイムシステムなどの機能を持ちます。