Sinatra / Ruby时区在开发与发展之间遇到麻烦生产

时间:2012-11-10 02:07:59

标签: ruby datetime timezone sinatra datamapper

我的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对象?

1 个答案:

答案 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时间字符串具有-08:00
  • 是与实际时间相同的JSON字符串吗?
  • 例如,如果您期望10:00Z,JSON是否显示02:00-08:00(即相同的实际时间)或10:00-08:00(实际时间不同 - 这是8几个小时后)。

如果数据往返有效,并且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)。