web-dev-qa-db-ja.com

Rails:postgresでタイムゾーンを使用して時間列を作成する方法

postgres dbで動作するRailsアプリケーションがあります。 UserTimingsというモデルがあり、from_timeとto_timeの2つのフィールドがあります。

t.time     "from_time"
t.time     "to_time"

時刻は、タイムゾーン情報とともに完全なUTC形式で保存されることを期待していました。しばらくして、データベースにテーブルを作成するためのこの種のSQLクエリがあることに気付きました。

from_time time without time zone,
to_time time without time zone,

これいらない。 タイムゾーンで保存したい。 Railsアプリケーションはそれを処理するように構成されていますが、UTC時間に+0530のものが必要です。データベースに使用を強制するための移行の記述方法を教えてください。タイムゾーン。

ありがとうございました。

14

その移行はまさにあなたが望むことをします

class CreatePeppers < ActiveRecord::Migration
  def change
    create_table :peppers do |t|
      t.column :runs, 'timestamp with time zone'
      t.column :stops, 'time with time zone'
    end
  end
end

タイプはあなたの選択です。ここには、postgresqlがサポートする任意のタイプを記述できます。ただし、型への変換には問題がある可能性があり、Railsは理解できます。

14
Dimitri

ここでは、2つの別々のことについて混乱しているようです。どちらもよくある間違いで、ほとんどの人が少なくとも1つは間違いを犯しています。

まず、「タイムゾーン情報を含むUTC形式」は時間を指定していません。時間と場所を指定しています。

第二に、PostgreSQLの「タイムゾーン付きタイムスタンプ」は実際にはタイムゾーンを保存しません。 UTCタイムスタンプを保存しますが、acceptsタイムゾーンです。名前のより良い選択は、「絶対時間」のようなものです。これらの値の2つを直接比較できます。

タイムゾーンのないタイムスタンプは、場所がない限り、実際には時間を与えません。それぞれがどのタイムゾーンにあるかを知らない限り、これらの2つを比較することはできません。

それはあなたが望むもののように聞こえますisタイムゾーンと個別のタイムゾーンのないタイムスタンプ。そうすれば、「火曜日の午後2時、ロンドン時間」と言うことができます。

3
Richard Huxton

これがあなたの望むものかどうかはわかりませんが、これは私にとってはうまくいきます:

add_column :table, :from_time, :timetz
add_column :table, :to_time, :timetz

しかし、Railsはtimetzタイプを認識できないようで、文字列として扱われます。これを回避するために、timetzをtimeとして登録します。

ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.class_eval do
  def initialize_type_map_with_postgres_oids mapping
    initialize_type_map_without_postgres_oids mapping
    register_class_with_limit mapping, 'timetz',
                              ActiveRecord::ConnectionAdapters::PostgreSQLAdapter::OID::Time
  end

  alias_method_chain :initialize_type_map, :postgres_oids
end

ところで、私の環境はRails-4.2です

1
HFX