我觉得以前有人问过这个问题,但到目前为止,没有一个解决方案对我有用。
由于使用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)
任何帮助将不胜感激:)
我认为你根本不需要编写任何代码。在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)
当然,您应该添加一些缺失值的检查,使其适应您自己的代码等。
这里有一篇关于 Rails 中时区的文章(由我撰写),可能会帮助你更清楚地思考这个问题。