TLDR
我有一个RoR3应用程序在PostgreSQL数据库上运行,我正在为该数据库编写功能测试。我注意到了一些特殊的东西,这导致了很多测试问题:时间是从一个选择中返回的,转换成了我的本地时间,但声称是UTC。
基本上,当我运行测试时,我会创建如下时间:
appointment_time = 1.day.from_now
打印输出(puts appointment_time
)输出
2014-01-08 20:08:14 UTC
但当我在那个时间(插入数据库后)进行选择并打印出来(puts professional.appointment_time
)时,它会显示
2014-01-08 15:08:14 UTC
注意有5个小时的差异-这是有道理的,因为我所在的东部时间比UTC晚了5个小时。但也要注意,返回的时间声称在UTC,所以它似乎在EST,但认为在UTC!
尽管我的application.rb
文件包含
# configure the default timezone for app and db
config.time_zone = 'UTC'
config.active_record.default_timezone = 'UTC'
更多信息和代码
以这些类为例:
def Professional
has_many :appointments
end
def Appointment
belongs_to :professional
attr_accessible :start_time
end
以及以下来自AppointmentController.rb
的片段:
def create
appointment = Appointment.new(params[:appointment])
if (conflicts?(appointment))
head :conflict
else
head :created
end
end
在ProfessionalControllerTest
中,我有以下
test 'add conflicting appointment returns conflict' do
professional = create(:professional)
start_time = 1.day.from_now
post :create, { professional_id: professional.id, appointment: { start_time: start_time } }
puts "ORIGINAL TIME: #{start_time}"
puts "SELECTED TIME: #{professional.appointments.first.start_time}"
assert_response :success
post :create, { professional_id: professional.id, appointment: { start_time: start_time } }
assert_response :conflict
end
这个测试应该通过,因为第一次发布到create
会创建一个约会,然后会导致第二次发布因为调用conflicts?
而返回冲突,但它失败了,因为第二次响应实际上是成功的!这里的输出看起来像:
原始时间:2014-01-08 20:08:14 UTC
选定时间:2014-01-08 15:08:14 UTC
再说一次,我在美国东部时间,比UTC晚了5个小时,所以我可以想象看到这样的情况:
2014-01-08 15:08:14 EST
这很有道理,但似乎在某个地方时间被转换为EST,但仍然认为是UTC。
如前所述,我的application.rb有这两行:
config.time_zone = 'UTC'
config.active_record.default_timezone = 'UTC'
所以我今天在一个不同的场景中偶然发现了这一点。事实证明
config.active_record.default_timezone
如果传递任何它不理解的内容,则默认为:local
。它不理解UTC
,这就是我传递它的内容!(由于config.time_zone = "UTC"
工作,所以有点不一致。要将其设置为UTC,您必须通过"UTC":
config.active_record.default_timezone=:utc
所以要明确的是,我的应用程序.rb现在包含:
config.time_zone = 'UTC'
config.active_record.default_timezone = :utc