我的Sinatra应用程序正在创建一个简单的对象并将其持久化到Postgres:
post '/' do
event = Event.new(params)
event.created_at = Time.now.utc
event.date = next_date(params[:dayofweek], params[:time]) if params[:dayofweek] && params[:time]
if event.save
status 201
event.to_json
else
json_status 400, event.errors.to_hash
end
def next_date(dayofweek, hour)
...
# some calculations that effectively culminate in the final line below
...
my_time = Time.utc(2012, 11, 9, 12, 0, 0) ## => 2012-11-09 12:00:00 UTC
end
对象保存成功。但是当我从development
环境中检索对象时,我得到了(json):
{ ..., "date":"2012-11-23T20:00:00-08:00" } #notice the PST offset of -08:00.
我期待UTC时区或 +00:00
。出于某种原因,我在PST中的开发工作站在保存到Postgres时考虑了自己的时区...至少它看起来在做什么?!?
将相同的代码发送到生产服务器(Heroku),以+00:00
的正确偏移量存储相同的数据
如何让我的开发工作站像生产工作站一样?或者,我应该如何在Sinatra中创建正确的UTC Date对象?
答案 0 :(得分:2)
首先验证您的数据是否成功往返:
event.created_at = Time.now.utc
event.date = ...whatever...
tmp_created_at = event.created_at
tmp_date = event.date
event.save
event.reload!
tmp_created_at == event.created_at or raise "created_at failed"
tmp_date == event.date_at or raise "date failed"
其次,验证JSON是否准确。
如果数据往返有效,并且JSON与实际时间相同,那么请查看您用于打印字符串的任何JSON库。寻找像“iso8601”这样的方法,它将以标准UTC格式打印时间。
此外,默认情况下,知道Postgres会在没有时区的情况下保存时间戳可能会有所帮助。
“SQL标准要求只写时间戳等同于没有时区的时间戳,PostgreSQL会尊重这种行为。(7.3之前的版本将其视为带时区的时间戳。)timestamptz被接受为timestamp随时间的缩写zone;这是一个PostgreSQL扩展。“
您可以通过描述表格来看到这一点,该表格可能如下所示:
# \d events
Table "public.events"
Column | Type | Modifiers
-----------+-----------------------------+-----------------------------------
id | integer | not null default
name | character varying(255) |
created_at | timestamp without time zone | not null
updated_at | timestamp without time zone | not null
date | timestamp with time zone | not null
基于OP反馈的更多信息...
OP说:我正在使用DataMapper,在他们的网站上挖掘后,我发现“时间属性将始终在数据存储区设置为的时区中存储和检索”以及指向某个特定部分的宝石的链接区。由于往返显示问题,请尝试使用当前版本的连接库,例如当前的DataMapper,并尝试任何类似库的当前版本,例如ActiveRecord(撰写本文时的版本3.2.8)。