4e0322e79d041875f3ef7db64e2d5b18

I'm mainly interested in optimizing the date_range_by_week function. Is there a more efficient way to split up the days by week?

def first_day_of_month(selected_date)
  selected_date.strftime('%Y-%m-01').to_date
end

def offset(selected_date)
  wday = first_day_of_month(selected_date).wday
  wday == 0 ? 6 : (wday - 1)
end

def start_date(selected_date)
 first_day_of_month(selected_date) - offset(selected_date)
end

def end_date(selected_date)
 (first_day_of_month(selected_date) - offset(selected_date)) + 41
end

def date_range_by_week(selected_date)
  date_range_by_week = []; date_range = []; 
  start_date(selected_date).upto(end_date(selected_date)) { |date| date_range << date }
  until date_range.empty?
    week = []
    7.times do |i|
      week << date_range.shift
    end
    date_range_by_week << week
  end
  date_range_by_week
end

def calender_header
  puts "



.-----------------------------------------------------------------------------,
| monday    | tuesday  | wednesday| thursday | friday   | saturday | sunday   |
"
end

def highlight?(day, date)
  day == Date.today or day == date
end

def paint_calendar(date)
  calender_header
  date_range_by_week(date).each_with_index do |week, i|
    next if week[0].month > date.month or week[0].year != date.year
    print ".--week[##{week[0].strftime('%W')}]-----------------------------------------------------------------.\n| "
    7.times do |i| 
      daystr = week[i].strftime('%b %d')
      spacer = highlight?(week[i], date) ? '==' : '  '
      print "#{spacer}#{daystr}#{spacer}|"
      print "\n" if i == 6
    end
  end
  puts "+-----------------------------------------------------------------------------+"
end
# >> paint_calendar Date.today
# 
# 
# 
# 
# .-----------------------------------------------------------------------------,
# | monday    | tuesday  | wednesday| thursday | friday   | saturday | sunday   |
# .--week[#08]-----------------------------------------------------------------.
# |   Feb 23  |  Feb 24  |  Feb 25  |  Feb 26  |  Feb 27  |  Feb 28  |  Mar 01  |
# .--week[#09]-----------------------------------------------------------------.
# |   Mar 02  |  Mar 03  |  Mar 04  |  Mar 05  |  Mar 06  |  Mar 07  |  Mar 08  |
# .--week[#10]-----------------------------------------------------------------.
# |   Mar 09  |  Mar 10  |  Mar 11  |  Mar 12  |  Mar 13  |  Mar 14  |  Mar 15  |
# .--week[#11]-----------------------------------------------------------------.
# |   Mar 16  |  Mar 17  |  Mar 18  |  Mar 19  |  Mar 20  |  Mar 21  |  Mar 22  |
# .--week[#12]-----------------------------------------------------------------.
# |   Mar 23  |  Mar 24  |==Mar 25==|  Mar 26  |  Mar 27  |  Mar 28  |  Mar 29  |
# .--week[#13]-----------------------------------------------------------------.
# |   Mar 30  |  Mar 31  |  Apr 01  |  Apr 02  |  Apr 03  |  Apr 04  |  Apr 05  |
# +-----------------------------------------------------------------------------+
# => nil
# >>

Refactorings

No refactoring yet !

7f00244a6387413b37ee449f234ec045

Marc-Andre

March 25, 2009, March 25, 2009 17:26, permalink

1 rating. Login to rate!

I'm presuming you're coding in rails, or at least using 'activesupport', so there is no need for your 'first_day_of_month' method. Use DateTime.beginning_of_month. Also, you were looking for Array.in_groups_of (activesupport) or Enumerable.group_by (ruby 1.9). Here's the result:

def offset(selected_date)
  wday = selected_date.beginning_of_month.wday
  wday == 0 ? 6 : (wday - 1)
end

def start_date(selected_date)
 selected_date.beginning_of_month - offset(selected_date)
end

def end_date(selected_date)
 (selected_date.beginning_of_month - offset(selected_date)) + 41
end

def date_range_by_week(selected_date)
  (start_date(selected_date)..end_date(selected_date)).to_a.in_groups_of(7)
end
7f00244a6387413b37ee449f234ec045

Marc-Andre

March 25, 2009, March 25, 2009 17:44, permalink

1 rating. Login to rate!

And if you don't need those extra methods, it's really a two line job, and you can change the beginning of the week easily:

def date_range_by_week(selected_date)
  first_in_calendar = selected_date.beginning_of_month.next_week(:monday) - 7
  (first_in_calendar...(first_in_calendar+7*6)).to_a.in_groups_of(7)
end
4e0322e79d041875f3ef7db64e2d5b18

Bonobo

March 25, 2009, March 25, 2009 19:12, permalink

No rating. Login to rate!

Lesson learned! (Read the Ruby/Rails docs closer) Thanks like 9000 times, Marc-André

D41d8cd98f00b204e9800998ecf8427e

bob

March 25, 2009, March 25, 2009 19:57, permalink

No rating. Login to rate!
def date_range_by_week(selected_date)
  (start_date(selected_date)..end_date(selected_date)).enum_slice(7).to_a
end

Your refactoring





Format Copy from initial code

or Cancel