支持Rails应用程序中的时区

时间:2012-09-23 07:53:33

标签: ruby-on-rails datetime

我在rails应用程序中添加了一个日历。我们有包含开始日期和结束日期(包括小时和分钟)的活动。这些是事件表中的字段,实际上它们的格式是datetime。当您为特定事件选择开始日期,结束日期,标题和描述(以及其他)时,参数哈希是这样的:

parameters = {"event" => {"title" => "a title", "description" => "a description", "start_date" => "2012-09-23 23:45", "end_date" => "2012-09-24 15:32"}}

在事件控制器中我有这样的事情:

Event.create(:title => params[:event][:title],
             :description => params[:event][:description],
             :start_date => params[:event][:start_date].present? ? DateTime.strptime(params[:event][:start_date], "%Y-%m-%d %H:%M") : nil,
             :end_date => params[:event][:end_date].present? ? DateTime.strptime(params[:event][:end_date], "%Y-%m-%d %H:%M") : nil,
             ...
            )

好吧,当此事件存储到数据库(mysql)中时,开始日期的值为“2012-09-23 20:45”,而结束日期的值为“2012-09-24 12:32”。我知道Rails会自动处理时区。我的问题是,当我想要获取特定时间内的所有事件时(例如,今天发生的所有事件),我会这样做:

query = "((start_date between ? AND ?) OR (end_date between ? AND ?))"
query << "title NOT LIKE ? AND ..."
self.events.where(query, 
                  Time.now.beginning_of_day, Time.now.end_of_day, 
                  Time.now.beginning_of_day, Time.now.end_of_day, 
                  some_restriction_here, ...)

我得到错误的事件! (很明显为什么,数据库中的日期和时间与输入不同)。还有明显的解决方案,将所有事件带入内存,日期和时间将再次与原始事件相同,但这在资源方面是昂贵的。另一方面,这并没有解决时区问题,如果中国某人创建事件,数据库中的值将相对于服务器本地化的时间偏移。我可以在某个地方设置一个用户可以设置时区的字段,然后使用这个字段为这样的用户存储特定日期并完成此操作,您有什么建议来解决这个问题的最佳方法?

1 个答案:

答案 0 :(得分:1)

Rails以UTC格式存储数据库中的所有日期。因此,一种方法是始终以UTC格式进行操作,并在视图中将显示的日期转换为当前时区。另一种方法是在每个操作的开头更改Rails时区。所有解析的时间和日期将在您的自定义时区。

def action_name
  Time.zone = "Prague"
  # ... logic
end