Asarluhi
Asarluhi

Reputation: 1290

Rails datetime comparison

My application offers the opportunity to create events with a start date and an end date with a certain format. Events should not last longer than two weeks, so the events controller check this condition with a before_action:

def correct_time
  @event = current_user.events.build(event_params)
  if (@event.end_time.to_datetime - @event.start_time.to_datetime) > 2.weeks
    flash[:danger] = "Attention! Events cannot last longer than 2 weeks"
    redirect_to root_url
  end
end

So I was puzzled when I was able to create the following event, which lasts 22 days:

>> event = Event.last
=> #<Event id: 1, user_id: 1, place: "barcelona", start_time: "2017-12-24 10:26", end_time: "2018-01-15 10:26", created_at: "2017-12-15 09:27:13", updated_at: "2017-12-15 09:27:13">

Apparently the condition does not work because Rails mistakes days with seconds:

>> (event.end_time.to_datetime - event.start_time.to_datetime)
=> (22/1)

>> (event.end_time.to_date - event.start_time.to_date) > 2.weeks
=> false

>> (event.end_time.to_datetime - event.start_time.to_datetime) == 22.days
=> false

>> (event.end_time.to_datetime - event.start_time.to_datetime) == 22.seconds
=> true

I do not know why this happens and how to solve it, apart from using 14.seconds instead of 2.weeks in the above expression, but that would not be correct.

Upvotes: 2

Views: 4238

Answers (2)

Martin Schneider
Martin Schneider

Reputation: 3268

Why not just use the integer, without the .days?

(event.end_time.to_date - event.start_time.to_date) == 22 # => true

Or convert to time objects:

(@event.end_time.to_time - @event.start_time.to_time) > 2.weeks

There are tons of possibilities to count the number of days between two dates, but the comparison has to be made using an integer:

(event.start_time.to_date..event.end_time.to_date).count > 14 

see How can I find the number of days between two Date objects in Ruby?

Upvotes: 4

Gokul
Gokul

Reputation: 3231

You can check the event duration as below:

if (@event.end_time.to_datetime - @event.start_time.to_datetime).to_i > 14
  flash[:danger] = "Attention! Events cannot last longer than 2 weeks"
  redirect_to root_url
end

Upvotes: 1

Related Questions