我觉得以前曾经问过这个问题,但到目前为止还没有一个解决方案适合我。
由于使用Heroku,我也被绑在Postgres(目前)
我存储了一个包含时间和时区的预订。
然后我需要将该时间转换为UTC,以便我可以在适当的时间用它执行功能
所以我有@booking.arrival_date
和@booking.time_zone
到目前为止,我的解决方案是:
Time.zone = @booking.time_zone
arrival_date = Time.zone.parse @booking.arrival_date.to_s
@booking.arrival_date = arrival_date.utc
@booking.save
但这不起作用。编辑:目前该值保留在用户选择的时间内(并未转换为UTC)
非常感谢任何帮助:)
答案 0 :(得分:1)
我认为你根本不需要编写任何代码。在config/application.rb
中查找您已设置应用程序时区的内容。默认为UTC,您应该保持这种状态。同时查看Postgres默认时区。如果你在Heroku上也应该是UTC。
由于这是Rails,因此您的列很可能是TIMESTAMP WITHOUT TIME ZONE
。然后在内部所有时间将自动存储在UTC中。因此,如果您想对它们进行计算,请继续。
这绝对不好:Time.zone = @booking.time_zone
。 Time.zone
值是一个全局变量,部分是Rails'组态。通过设置它,您使代码线程不安全(可能无关紧要)并让一个请求污染另一个(可能确实如此)。如果你需要把它放在某个地方,可以说tz = @booking.time_zone
。
现在你可能做需要做的就是解析用户提交的时间字符串,从给定的时区解释它。这是你在控制器中处理的事情:
h = booking_params
tz = ActiveSupport::TimeZone[h[:time_zone]]
h[:arrival_date] = tz.parse h[:arrival_date]
@booking = Booking.new(h)
当然,您应该为缺失值添加一些检查,使其适应您自己的代码等。
这是article on time zones in Rails(由我),可以帮助您更清楚地考虑这一点。