如何使用Ruby和MongoId正确保存时区?

如果这是一个noob问题,请原谅我:

我有一个应用程序,用户可以在他们的个人资料中设置自己的时区。

当有人添加阵容(特定于应用程序的术语)时,我会执行以下操作:

time = ActiveSupport::TimeZone.new(user.timezone).parse( "Wednesday, 26 October, 2011 13:30:00" ) # This outputs: 2011-10-26 13:30:00 +0200 - valid according to the user selected TZ 

然后我保存阵容:

 Lineup.create({ :date => time.gmtime, :uid => user._id, :pid => product._id }) 

这应该(理论上)将日期保存为gmtime,但在查看记录时我会得到以下信息:

 { "_id": ObjectId("4e9c6613e673454f93000002"), "date": "Wed, 26 Oct 2011 13: 30: 00 +0200", "uid": "4e9b81f6e673454c8a000001", "pid": "4e9c6613e673454f93000001", "created_at": "Mon, 17 Oct 2011 19: 29: 55 +0200" } 

正如您所看到的,日期字段错误 – 它仍然保持用户时区,它应该是GMT,而不是特定于时区。

如果我输出time.gmtime,我会得到正确的时间(应该保存):

 2011-10-26 11:30:00 UTC (correct) 

有任何想法如何保存GMT日期,以便它实际保存GMT日期?

看起来您需要指定日期属性的字段类型。 如果你想要mongoid正确处理区域,我会使用时间字段。

 class Lineup include Mongoid::Document field :date, type: Time end 

您可能还想在config / mongoid.yml中设置以下内容

 defaults: &defaults use_utc: false use_activesupport_time_zone: true 

这听起来违反直觉,但这是使mongoid使用UTC作为默认时区的当前方法。

最后,看看mongoid-metastamp gem。 它将为您提供更好的支持,可以跨多个时区进行查询,同时仍然可以像本机时间字段一样无缝地工作。