关于rails上的ruby:在更新用户输入的时区后以UTC格式存储日期以反映正确的UTC时间

Storing dates in UTC after updating the user entered time zone to reflect proper UTC time

我有一个事件模型,它有开始和结束日期/时间以及相关的时区。

我需要提交的日期时间根据输入的时区存储在正确的UTC版本中。

例如,如果用户提交2014-04-24美国东部时间晚上7点

数据库应该是:

2014-04-24T23:00:00.000Z

不是这个:

2014-04-24T19:00:00.000-07:00

好吧,我知道rails存储了UTC中的所有内容,但我需要根据时区存储更新的UTC时间 - 因为我的表单是3个字段,x2日期/时间& x1时区

这是我认为可以正常工作的模型验证:

1
2
3
4
5
6
7
8
9
10
11
12
  def calc_utc_based_off_timezone
    time_zone = self.time_zone

    puts"start date before assignment:"
    puts self.start_date

    self.start_date = self.start_date.in_time_zone(time_zone)
    self.end_date = self.end_date.in_time_zone(time_zone)

    puts"start date after assignment:"
    puts self.start_date
  end

以我的形式输入:

2014-04-24 - 19:00

2014-04-26 - 19:00

est

输出:

start date before assignment:

2014-04-24 19:00:00 UTC

start date after assignment:

2014-04-24 19:00:00 UTC

我期待的是:

start date before assignment:

2014-04-24 19:00:00 UTC

start date after assignment:

2014-04-24 23:00:00 UTC <-- updated UTC to reflect the time zone

任何帮助将不胜感激,谢谢。


在ActiveSupport :: TimeWithZone类中支持带有时区的Time对象。
只要在将参数提供给新对象函数之前设置时区Event.new(params[:event]) rails将应用设置的偏移量,并将其解释为在该时区中。

1
2
3
4
5
6
7
8
9
10
# example params like the request
params = {
          time_zone:"EST",
          event:{
            start_date:"2014-04-24 - 19:00",
            end_date:"2014-04-26 - 19:00"}
          }  

Time.zone = params[:time_zone] # pulled from a time_zone_select field
@event = Event.new(params[:event])

如果您有单独的时间和日期字段,只需将它们组合到数据库中保存日期时间的任何字段即可。

1
2
3
4
params[:event][:start_date] ="#{params[:event][:start_date]} #{params[:event][:start_time]}"
params[:event][:end_date] ="#{params[:event][:end_date]} #{params[:event][:end_time]}"

@event = Event.new(params[:event])

时区偏移将自动应用,如果检查对象,则应获得以下内容。

1
2
3
4
> puts @event.start_date
2014-04-25 00:00:00 UTC
> puts @event.end_date
2014-04-27 00:00:00 UTC

这是一个很棒的指南,涉及Rails和时区 - Rails时区的详尽指南


你是对的,Rails ActiveSupport中有一些东西,

1
2
3
4
5
6
7
Time.parse("2014-04-24 - 19:00").in_time_zone

Thu, 24 Apr 2014 23:00:00 UTC +00:00

Time.parse("2014-04-24 - 19:00").getutc

2014-04-24 23:00:00 UTC

您还可以通过传递其他参数来指定响应的详细信息和格式(如iso8601):

1
2
3
4
> Time.parse("2014-04-24 - 19:00").getutc.iso8601(2)
"2014-04-24T23:00:00.00Z"
> Time.parse("2014-04-24 - 19:00").getutc.iso8601(3)
"2014-04-24T23:00:00.000Z"

ActiveSupport :: TimeWithZone的文档:http://api.rubyonrails.org/classes/ActiveSupport/TimeWithZone.html#method-i-getutc