Chris Mendla
Chris Mendla

Reputation: 1017

Can't get date/time comparison working correctly in rails. Timezone issue.

I am trying to compare a date/time in a table with the current time to see if the item has expired. I've tried a lot of combinations but just can't seem to adjust properly for the timezone. I am in Eastern Standard time.

  create_table "admin_messages", force: :cascade do |t|
    t.text     "message"
    t.datetime "expires"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

The basic idea is that I can add a message and expiration date and show the messages that have not expired.

application.rb
    config.active_record.default_timezone = 'Eastern Time (US & Canada)'
    config.time_zone = 'Eastern Time (US & Canada)'
  end

I've tried a number of ways of getting the if statement below to work properly to no avail.

 helper_method :show_admin_messages
  def show_admin_messages
    $admin_message = ''
    @admin_messages = AdminMessage.all
    @admin_messages.each do |message|
      if message.expires >= Time.now.in_time_zone("Eastern Time (US & Canada)")

      $admin_message = $admin_message + message.message + "<br>"
      end
    end
  end

If I try a couple of variations on Time.now, I get:

Time.now 2016-01-19 09:23:08 -0500 
Time.now.utc 2016-01-19 14:23:08 UTC
Time.now.localtime 2016-01-19 09:23:08 -0500
Time.now.in_time_zone("Eastern Time (US & Canada)") 2016-01-19 09:23:08 -0500

My problem is trying to figure out the syntax for the if statement.

Upvotes: 0

Views: 101

Answers (2)

Frederick Cheung
Frederick Cheung

Reputation: 84132

First off you almost certainly don't want to set config.active_record.default_timezone. The default is utc - with other timezones you'll have issues such as DST making it appear that records were recreated in the wrong order an so on.

For the vast majority of applications the time zone is only relevant when presenting output to users or receiving input. An action such as filtering whether expires is in the past or in the present doesn't depend on this:

message.expires <= Time.now

will do it.

Event better would be

@admin_messages = AdminMessage.where('expires > ?', Time.now)

so that you only fetch unexpired messages from the database in the first place.

Upvotes: 1

mtkcs
mtkcs

Reputation: 1716

You can just use:

if message.expires.past?
  ## it expired
else
  ## not yet
end

Upvotes: 2

Related Questions