1

My Sinatra app is creating a simple object and persisting it to 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

Object saves successfully. But when I retrieve the object from my development environment I get (json):

{ ..., "date":"2012-11-23T20:00:00-08:00" }   #notice the PST offset of -08:00. 

I'm expecting the UTC time zone or +00:00. For some reason my development workstation, which is in PST, is factoring in its own time zone when saving to Postgres...at least that what it appears to be doing?!?

Sending the same code to the production server (Heroku) stores same data with proper offset of +00:00

How can I make my development workstation act like the production one? Or, how should I be creating a proper UTC Date object in Sinatra?

4

1 回答 1

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(不同的实际时间 - 这是八小时后) .

如果数据往返有效,并且 JSON 是相同的实际时间,则查看您用于打印字符串的任何 JSON 库。寻找像“iso8601”这样的方法,它将以标准 UTC 格式打印时间。

此外,知道 Postgres 默认保存没有时区的时间戳可能会有所帮助。

“SQL 标准要求仅写入时间戳等同于不带时区的时间戳,并且 PostgreSQL 尊重这种行为。(7.3 之前的版本将其视为带时区的时间戳。)时间戳被接受为带时区的时间戳的缩写;这是一个 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,在他们的网站上四处挖掘后,我发现“时间属性将始终在数据存储设置的时区中存储和检索”,以及指向将强制特定区域的 gem 的链接。

因为往返显示了问题,请尝试使用当前版本的连接库,例如当前的 DataMapper,并尝试使用任何类似库的当前版本,例如 ActiveRecord(撰写本文时版本为 3.2.8)。

于 2012-11-10T04:15:18.163 回答