Reputation: 2449
The following Ruby code gets me the first day of each month :
require 'active_support/all'
# get the date at the beginning of this month
date = Date.today.beginning_of_month
# get the first day of the next 5 months
5.times do |num|
date = date.next_month
p date
end
Which gives :
=> Fri, 01 Aug 2014
=> Mon, 01 Sep 2014
=> Wed, 01 Oct 2014
=> Sat, 01 Nov 2014
=> Mon, 01 Dec 2014
But how do I get the first Thursday of each month? i.e.
=> Thu, 07 Aug 2014
=> Thu, 04 Sep 2014
=> Thu, 02 Oct 2014
=> Thu, 06 Nov 2014
=> Thu, 04 Dec 2014
Upvotes: 4
Views: 1651
Reputation: 49
I ran into this problem for a recurring_events
feature that I needed to build. I changed some of the variables to find the first Thursday but it also shows how you could evolve the answer to find the 2nd or 3rd Thursday (or any day of the week for that matter) if you had a week and day of the week count.
def find_thursday
start_of_month = DateTime.now.beginning_of_month
month_day = nil
loop do
month_day = start_of_month += 1.day
break if month_day.wday == find_weekday("Thu")
end
return month_day
end
def find_weekday
d = default_weekdays.find { |d| d[:day] == start_date.strftime("%a") }
d[:count]
end
def default_weekdays
return [
{ day: 'Sun', count: 0 },
{ day: 'Mon', count: 1 },
{ day: 'Tue', count: 2 },
{ day: 'Wed', count: 3 },
{ day: 'Thu', count: 4 },
{ day: 'Fri', count: 5 },
{ day: 'Sat', count: 6 },
]
end
Upvotes: -1
Reputation: 44360
That my opinion:
date_begin = Date.today.beginning_of_month
date_end = date_begin + 5.month
[*date_begin..date_end].select(&:thursday?).uniq(&:month)
=> [Thu, 03 Jul 2014, Thu, 07 Aug 2014, Thu, 04 Sep 2014, Thu, 02 Oct 2014, Thu, 06 Nov 2014]
Upvotes: 4
Reputation: 8295
you can use something like this:
def first_thursday(months_ahead)
start_of_month = months_ahead.months.from_now.beginning_of_month.to_date
start_of_month += (4 - start_of_month.cwday) % 7
end
first_thursday 1
=> Thu, 07 Aug 2014
first_thursday 2
=> Thu, 04 Sep 2014
Upvotes: 1
Reputation: 5795
There's no need for iterations or conditions just get the so called delta of days till next thursday:
#4 is thursday because wday starts at 0 (sunday)
date = Date.today.beginning_of_month
date += (4 - date.wday) % 7
p date
=> Thu, 03 Jul 2014
Upvotes: 10
Reputation: 230326
Just for fun
class Date
def skip_to_thursday
# given current weekday, how many days we need to add for it to become thursday
# for example, for monday (weekday 1) it's 3 days
offset = lambda {|x| (4-x) % 7 }
self + offset[wday]
end
end
# get the date at the beginning of this month
date = Date.today.beginning_of_month
date.skip_to_thursday # => Thu, 03 Jul 2014
Upvotes: 4
Reputation: 118271
Here is my way :
def first_thursday
date = Date.today.beginning_of_month
date += 1 until date.wday == 4
date
end
first_thursday # => Thu, 03 Jul 2014
Upvotes: 2