Rails:如何在postgres上创建带时区的时间列

时间:2013-10-06 10:34:34

标签: ruby-on-rails postgresql timezone utc

我有一个 rails 应用程序,适用于 postgres db。我有一个名为UserTimings的模型,其中有两个字段from_time和to_time。

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

我预计时间将以完整的UTC格式存储,并带有时区信息。过了一会儿,我意识到数据库有这种SQL查询来创建表。

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

我不想要这个。我想用时区存储。我希望UTC时间里有+0530的东西,我还没想到rails应用程序已被配置为处理它。请告诉我如何编写迁移以强制数据库使用时区。

谢谢。

3 个答案:

答案 0 :(得分:13)

迁移完全符合您的要求

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支持。但转换为类型可能存在问题,导轨可以理解。

答案 1 :(得分:3)

你似乎对这里的两件事情感到困惑 - 这两件事都是常见错误,几乎每个人至少都会犯下其中一件事。

首先,“带有时区信息的UTC格式”没有指定时间。它指的是时间和地点。

其次PostgreSQL的“带时区的时间戳”实际上并不存储时区。它存储UTC时间戳,但接受时区。更好的名称选择就像“绝对时间”。您可以直接比较其中两个值。

没有时区的时间戳实际上并没有给你时间,除非你还有一个地方。除非您知道每个时区属于哪个时区,否则无法对其中的两个进行比较。

这听起来像你想要的没有时区和单独时区的时间戳。这样你就可以说“伦敦时间星期二下午2点”。

答案 2 :(得分:1)

不确定这是你想要的,但这对我有用:

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

但是rails似乎无法识别timetz类型,它将被视为String。为了解决这个问题,我将timetz注册为时间。

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

BTW,我的环境是rails-4.2