Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to save a timezone correctly with Ruby and MongoId?

Please excuse me if this is a bit of a noob issue:

I have an app where users can set their own Timezones in their profile.

When someone adds a Lineup (app specific terminology), I do the following:

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

I then save the Lineup:

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

This should (in theory) save the date as gmtime, but I get the following when viewing the record:

{
  "_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"
}

As you can see the date field is wrong - it still maintaining the user timezone, it should be GMT, not timezone specific.

If I output time.gmtime, I get the right time (that should be saved):

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

Any ideas how to save the GMT date so that it actually saves the GMT date?

like image 943
ghstcode Avatar asked Oct 17 '11 17:10

ghstcode


1 Answers

It looks like you need to specify the field type of your date attribute. I would use a Time field if you want mongoid to handle the zones properly.

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

You will also probably want to set the following in config/mongoid.yml

defaults: &defaults
  use_utc: false
  use_activesupport_time_zone: true

This sounds counterintuitive, but this is the current way to make mongoid use UTC as the default timezone.

Finally, have a look at the mongoid-metastamp gem. It will give you much better support for querying across multiple timezones, while still seamlessly working like a native Time field.

like image 63
sporkd Avatar answered Oct 31 '22 10:10

sporkd