7.24. Dividing a Month into WeeksImagine that you wanted to divide a month into weeksfor example, to print a calendar. The following code does that. The array returned is made up of subarrays, each of size seven (7); Sunday corresponds to the first element of each inner array. Leading entries for the first week and trailing entries for the last week may be nil. def calendar(month,year) days = month_days(month,year) t = Time.mktime(year,month,1) first = t.wday list = *1..days weeks = [[]] week1 = 7 - first week1.times { weeks[0] << list.shift } nweeks = list.size/7 + 1 nweeks.times do |i| weeks[i+1] ||= [] 7.times do break if list.empty? weeks[i+1] << list.shift end end pad_first = 7-weeks[0].size pad_first.times { weeks[0].unshift(nil) } pad_last = 7-weeks[0].size pad_last.times { weeks[-1].unshift(nil) } weeks end arr = calendar(12,2008) # [[nil, 1, 2, 3, 4, 5, 6], # [7, 8, 9, 10, 11, 12, 13], # [14, 15, 16, 17, 18, 19, 20], # [21, 22, 23, 24, 25, 26, 27], # [28, 29, 30, 31, nil, nil, nil]] To illustrate it a little better, the following method prints out this array of arrays: def print_calendar(month,year) weeks = calendar(month,year) weeks.each do |wk| wk.each do |d| item = d.nil? ? " "*4 : " %2d " % d print item end puts end puts end # Output: # 1 2 3 4 5 6 # 7 8 9 10 11 12 13 # 14 15 16 17 18 19 20 # 21 22 23 24 25 26 27 # 28 29 30 31 |