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

我有一个适用于postgres db的rails应用程序。 我有一个名为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应用程序已被配置为处理它。 请告诉我如何编写迁移以强制数据库使用时区。

谢谢。

迁移完全符合您的要求

 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可以理解。

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

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

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

没有时区的时间戳实际上并没有给你时间,除非你还有一个地方。 你不能比较其中的两个,除非你知道每个时区。

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

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

 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 

顺便说一句,我的环境是rails-4.2