21

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

谢谢你。

4

3 回答 3

23

该迁移完全符合您的要求

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

于 2014-02-20T19:49:29.753 回答
5

您似乎对这里的两个不同的事情感到困惑-都是常见的错误,几乎每个人都至少犯了一个。

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

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

没有时区的时间戳实际上并没有给你一个时间,除非你也有一个地方。除非您知道每个时区所在的时区,否则您无法比较其中两个。

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

于 2013-10-06T14:34:22.000 回答
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

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

于 2017-04-18T06:37:10.697 回答