Reputation: 27222
My date methods aren't working correctly on Heroku. I created a user that goes by the (GMT-05:00) Eastern Time (US & Canada)
and is suppose to see products added based on the date
attribute it has. So it suppose to say Added 1 Product Today
but it's as if it's the methods themselves are recording by the day before. So today
is actually yesterday and yesterday
is actually the day after yesterday.
Here are my methods:
def self.today
where(:date => Date.today)
end
def self.yesterday
where(:date => Date.yesterday)
end
def self.this_week
where(:date => Date.today.beginning_of_week..Date.today.end_of_week)
end
def self.last_week
where(:date => 1.week.ago.beginning_of_week..1.week.ago.end_of_week)
end
def self.this_month
where(:date => Date.today.beginning_of_month..Date.today.end_of_month)
end
def self.last_month
where(:date => 1.month.ago.beginning_of_month..1.month.ago.end_of_month).order('date desc')
end
So I guess it's always -1 day
for every method on Heroku but not in development. Heroku's Time zone and Time are:
Loading production environment (Rails 3.2.8)
irb(main):001:0> Time.now
Time.now
=> 2012-09-21 02:37:26 +0000
irb(main):002:0> Time.zone
Time.zone
=> (GMT+00:00) UTC
This is wrong for me since it's 2012-09-20
in the US East.
I want to have the methods work for every Timezone, not just Eastern Timezone
so what should I do about this? How can I get a user to see the products they've added based on their Timezone?
Thank you.
Upvotes: 2
Views: 580
Reputation: 1572
You need to prefix time point search functions with in_time_zone. For example Date.today.beginning_of_week
should be Date.today.in_time_zone(users_tz).beginning_of_week
.
Upvotes: 1
Reputation: 23
add this line into application.rb under config folder
config.active_record.default_timezone = 'GMT + 5.30'
Upvotes: 0
Reputation: 11510
Well, if you wanted one time zone globally, the easiest way to do that is to heroku config:set TZ
to some suitable value. That covers everything from libc on up.
However, user-specific time zones means you need to change the time zone within the context of each request. "Each request" should immediately make you think "in the controller".
It turns out that Rails (specifically, ActionSupport) makes provisions for this with Time.zone=
. It also just so happens that this is common enough that the zone=
documentation includes sample code specifically for this scenario:
class ApplicationController < ActionController::Base
around_filter :set_time_zone
def set_time_zone
old_time_zone = Time.zone
Time.zone = current_user.time_zone if logged_in?
yield
ensure
Time.zone = old_time_zone
end
end
Also, if you can't get users to select their time zone from a list, you can guess based on the time zone offset detected in JavaScript. It's better than nothing.
Upvotes: 2