将 DateTime 保存到数据库:时区错误

Save DateTime to Database: Timezone Error

提问人:Jens Schmidt 提问时间:8/23/2011 最后编辑:rpyJens Schmidt 更新时间:5/19/2016 访问量:6497

问:

我已经设置

config.time_zone = 'Berlin'
config.active_record.default_timezone = :local

在“application.rb”中,重新启动WEBrick Webserver,一个“remigrated”(rake db:drop;rake db:migrate)我的数据库。

如果我检查数据库中的条目,一切都很好,“created_at”正确保存在我的 Localtimezone 中:

sqlite> select created_at from docversions;
2011-08-22 23:27:51.138723
sqlite>

但在这种情况下,这个“本地时区”不起作用:

(creat.html.erb)

<%= form_for :token, :url => {:action => "save_token"}, :docversion_id => params[:id] do |f| %>
<%= f.datetime_select :validuntil, :order => [:day, :month, :year, :hour, :minute], :default => 3.days.from_now,  %>
<%= f.submit %>

(tokenadmin_controller.rb)

class TokenadminController < ApplicationController
  def save_token
    @token = Token.new
    civildate = DateTime.civil(params[:token]["validuntil(1i)"].to_i,
                               params[:token]["validuntil(2i)"].to_i,
                               params[:token]["validuntil(3i)"].to_i,
                               params[:token]["validuntil(4i)"].to_i,
                               params[:token]["validuntil(5i)"].to_i)
    @token.validuntil = civildate
    if @token.save
      flash[:notice] = "Token created."
      redirect_to :controller => :tokenadmin, :action => :admin
    else
      flash[:error] = "Token could not be saved!"
      redirect_to :controller => "index"
    end 
  end 
end

似乎它会被保存为 UTC:

sqlite> select validuntil, created_at from tokens;
2011-08-22 01:44:00.000000|2011-08-22 23:44:20.640434
sqlite>

如您所见,created_at 被正确保存为 Localtime,但 validuntil 保存为 +2h(但我选择了与create_at相同的时间;-))。我认为它是 +2h,因为处于 UTC+1 和 DST UTC+2 的时区。并且目前处于夏令时状态。

这是一个错误,还是我做错了什么?

感谢您的帮助。

从“BaronVonBraun”发帖后更新:

谢谢!它现在正在工作。 Database字段仍为“timestamp”:

t.timestamp :validuntil

控制器代码,用于创建时间字段:

以前:

civildate = DateTime.civil(params[:token]["validuntil(1i)"].to_i,
                           params[:token]["validuntil(2i)"].to_i,
                           params[:token]["validuntil(3i)"].to_i,
                           params[:token]["validuntil(4i)"].to_i,
                           params[:token]["validuntil(5i)"].to_i)

后:

civildate = Time.parse("#{params[:token]["validuntil(1i)"].to_s}-#{params[:token]["validuntil(2i)"].to_s}-#{params[:token]["validuntil(3i)"].to_s} #{params[:token]["validuntil(4i)"].to_s}:#{params[:token]["validuntil(5i)"].to_s}")
Ruby-on-Rails-3 (轨道上的红宝石-3)

评论


答:

3赞 BaronVonBraun 8/23/2011 #1

DateTime默认情况下,对象处于 GMT/UTC(+0000 偏移量)中。

如果你想存储你的本地时区和你的日期对象,我建议使用代替,它应该使用你在 Rails 配置中设置的时区。TimeDateTime

如果您需要继续使用 ,这里是另一个问题的答案:如何在 Ruby 中更改 DateTime 的时区?。但是,在该解决方案中,它将时区设置为硬偏移量,这意味着它无法处理进出 DST。DateTime