LearningRoR
LearningRoR

Reputation: 27222

How to fix date methods from being off on heroku?

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

Answers (3)

iced
iced

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

Gayu
Gayu

Reputation: 23

add this line into application.rb under config folder

config.active_record.default_timezone = 'GMT + 5.30'

Upvotes: 0

willglynn
willglynn

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

Related Questions