#ruby-on-rails #ruby
#ruby-on-rails #ruby
Вопрос:
Следующий код Ruby возвращает мне первый день каждого месяца :
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
Что дает :
=> Fri, 01 Aug 2014
=> Mon, 01 Sep 2014
=> Wed, 01 Oct 2014
=> Sat, 01 Nov 2014
=> Mon, 01 Dec 2014
Но как мне получить первый четверг каждого месяца? т.е.
=> Thu, 07 Aug 2014
=> Thu, 04 Sep 2014
=> Thu, 02 Oct 2014
=> Thu, 06 Nov 2014
=> Thu, 04 Dec 2014
Ответ №1:
Нет необходимости в итерациях или условиях, просто получите так называемую дельту дней до следующего четверга:
#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
Ответ №2:
Это мое мнение:
date_begin = Date.today.beginning_of_month
date_end = date_begin 5.month
[*date_begin..date_end].select(amp;:thursday?).uniq(amp;:month)
=> [Thu, 03 Jul 2014, Thu, 07 Aug 2014, Thu, 04 Sep 2014, Thu, 02 Oct 2014, Thu, 06 Nov 2014]
Комментарии:
1. в haskell это, вероятно, было бы очень эффективно. В ruby — не так много 🙂
2.
.map { |x| x if x.thursday? }.compact
=>.select(amp;:thursday?)
Ответ №3:
Просто для удовольствия
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
Комментарии:
1. Я такой тупой.. кто все еще не понимает.. что этот хэш там делает .. можете ли вы сказать несколько слов для меня ? 🙂
2. попробуйте забавную лямбду:
offset = lambda {|x| (4-x) % 7 }
, чтобы вы могли использоватьoffset[2] #=> 2
3. @xlembouras: ого, умница 🙂
4. Или
offset = [4,3,2,1,7,6]
иoffset.index(wday)
5. Правильно-правильно. Это то, что было в первой версии. Посмотрите на историю редактирования 🙂
Ответ №4:
Вот мой способ :
def first_thursday
date = Date.today.beginning_of_month
date = 1 until date.wday == 4
date
end
first_thursday # => Thu, 03 Jul 2014
Ответ №5:
вы можете использовать что-то вроде этого:
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
Комментарии:
1. Не работает для июля или сентября. На самом деле, это, вероятно, чистая удача, что это работает в августе 🙂
Ответ №6:
Я столкнулся с этой проблемой для recurring_events
функции, которую мне нужно было создать. Я изменил некоторые переменные, чтобы найти первый четверг, но это также показывает, как вы могли бы развить ответ, чтобы найти 2-й или 3-й четверг (или любой день недели, если на то пошло), если у вас была неделя и количество дней недели.
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