Set a datetime for next or previous sunday at specific time

Go To StackoverFlow.com

1

I have an app where there is always a current contest (defined by start_date and end_date datetime). I have the following code in the application_controller.rb as a before_filter.

def load_contest
 @contest_last = Contest.last
 @contest_last.present? ? @contest_leftover = (@contest_last.end_date.utc - Time.now.utc).to_i : @contest_leftover = 0

 if @contest_last.nil?
  Contest.create(:start_date => Time.now.utc, :end_date => Time.now.utc + 10.minutes)
 elsif @contest_leftover < 0
  @winner = Organization.order('votes_count DESC').first
  @contest_last.update_attributes!(:organization_id => @winner.id, :winner_votes => @winner.votes_count) if @winner.present?
  Organization.update_all(:votes_count => 0)
  Contest.create(:start_date => @contest_last.end_date.utc, :end_date => Time.now.utc + 10.minutes)
 end
end

My questions:

1) I would like to change the :end_date to something that signifies next Sunday at a certain time (eg. next Sunday at 8pm). Similarly, I could then set the :start_date to to the previous Sunday at a certain time. I saw that there is a sunday() class (http://api.rubyonrails.org/classes/Time.html#method-i-sunday), but not sure how to specify a certain time on that day.

2) For this situation of always wanting the current contest, is there a better way of loading it in the app? Would caching it be better and then reloading if a new one is created? Not sure how this would be done, but seems to be more efficient.

Thanks!

2012-04-04 16:39
by Marc


3

Start with this snippet. In rails, given a date/time object d, the expression

d - wday.day

Gives the last Sunday not after that date. i.e. if the day itself is a Sunday the result will be d.

Then to get the next sunday:

sunday1 = d - wday.day
sunday2 = sunday1 + 7.day

And to set the times for both:

sunday1 = (d - wday.day).change(:hour => 8,:min => 30)
sunday2 = (sunday1 + 7.day).change(:hour => 20)

No need for any external modules. Rails (but not core ruby!) has all the date/time manipulation functionality you need.

Note how the change function works: if you pass it :hour only, it will reset the minute and second to 0. If you pass it :hour and :minute, it will reset only the second. See the docs for details.

One last thing: be mindful of what time zone you are using.

2012-04-05 07:58
by Michael Slade
Thanks. But ultimately how would I specify a time on those days (eg. 8pm est) - Marc 2012-04-05 11:31
answer updated - Michael Slade 2012-04-05 13:26
Looks good! I'm going to test it out tonigh - Marc 2012-04-05 16:23
Instead of :minute => 30 it should be :min => 30Shailesh Kalamkar 2012-11-19 07:38
You're right. Answer amended - Michael Slade 2012-11-19 11:35
Ads