这可能是作弊,但您可以通过使用 active_support 提供的日期函数大大简化代码。下面是我使用 active_support 提出的一些代码。该算法非常简单。算出第一个月的最后一天,算出最后一个月的第一天。然后打印第一个月,将中间分成年份并打印它们,然后打印最后一个月。当然,由于边缘情况,这个简单的算法在很多方面都失败了。下面的算法试图优雅地解决这些边缘情况。希望对你有帮助。
require 'active_support/all'
# Set the start date and end date
start_date = Date.parse("March 19, 2009")
end_date = Date.parse("July 15, 2011")
if end_date < start_date
# end date is before start date, we are done
elsif end_date == start_date
# end date is the same as start date, print it and we are done
print start_date.strftime("%B %e, %Y")
elsif start_date.year == end_date.year && start_date.month == end_date.month
# start date and end date are in the same month, print the dates and we
# are done
print start_date.strftime("%B %e, %Y"), " - ",
end_date.strftime("%B %e, %Y"), "\n"
else
# start date and end date are in different months
first_day_of_next_month = Date.new((start_date + 1.month).year,
(start_date + 1.month).month, 1);
first_day_of_end_month = Date.new(end_date.year, end_date.month, 1);
# print out the dates of the first month
if (first_day_of_next_month - 1.day) == start_date
print start_date.strftime("%B %e, %Y"), "\n"
else
print start_date.strftime("%B %e, %Y"), " - ",
(first_day_of_next_month - 1.day).strftime("%B %e, %Y"), "\n"
end
# now print the inbetween dates
if first_day_of_next_month.year == (first_day_of_end_month - 1.day).year &&
(first_day_of_end_month - 1.day) > first_day_of_next_month
# start date and end date are in the same year, just print the inbetween
# dates
print first_day_of_next_month.strftime("%B %e, %Y"), " - ",
(first_day_of_end_month - 1.day).strftime("%B %e, %Y") + "\n"
elsif first_day_of_next_month.year < (first_day_of_end_month - 1.day).year
# start date and end date are in different years so we need to split across
# years
year_iter = first_day_of_next_month.year
# print out the dates from the day after the first month to the end of the
# year
print first_day_of_next_month.strftime("%B %e, %Y"), " - ",
Date.new(first_day_of_next_month.year, 12, 31).strftime("%B %e, %Y"),
"\n"
year_iter += 1
# print out the full intermediate years
while year_iter < end_date.year
print Date.new(year_iter, 1, 1).strftime("%B %e, %Y"), " - ",
Date.new(year_iter, 12, 31).strftime("%B %e, %Y"), "\n"
year_iter += 1
end
# print from the begining of the last year until the last day before the the
# end month
print Date.new(first_day_of_end_month.year, 1, 1).strftime("%B %e, %Y"),
" - ", (first_day_of_end_month - 1.day).strftime("%B %e, %Y"), "\n"
end
# finally print out the days of the last month
if first_day_of_end_month == end_date
print end_date.strftime("%B %e, %Y"), "\n"
else
print first_day_of_end_month.strftime("%B %e, %Y"), " - ",
end_date.strftime("%B %e, %Y"), "\n"
end
end