我怎样才能获得每天的日期/数字?这是我的代码:
class Month
attr_reader :month, :year
def initialize( month, year)
@month = month
@year = year
end
def month_names
names_of_months = {1 => 'January', 2 => 'February', 3 => 'March', 4 => 'April', 5 => 'May', 6 => 'June', 7 => 'July', 8 => 'August', 9 => 'September', 10 => 'October', 11 => 'November', 12 => 'December'}
return names_of_months[@month]
end
def length
days_of_months = {1 => 31, 2 => 28, 3 => 31, 4 => 30, 5 => 31, 6 => 30, 7 => 31, 8 => 31, 9 => 30, 10 => 31, 11 => 30, 12 => 31}
return days_of_months[@month]
end
def to_s
weekdays = "Su Mo Tu We Th Fr Sa"
month = "#{month_names} #{year}"
output = [
month.center(weekdays.size),
weekdays
].join("\n")
(1..length).each do |day|
output << day.to_s
end
output
end
end
以下是我的结果。
January 2017
Su Mo Tu We Th Fr Sa12345678910111213141516171819202122232425262728293031
答案 0 :(得分:2)
由于您的问题已经被诊断出来,我将限制我的答案,以展示如何使用课程Date。
<强>代码强>
require 'date'
DAY_WIDTH = 4
def calendar(year, month)
title = "#{Date::MONTHNAMES[month]}, #{year}".center(7*DAY_WIDTH)
puts "\n#{title}"
Date::ABBR_DAYNAMES.each { |s| print s.rjust(DAY_WIDTH) }
puts
arr = [*[' ']*Date.new(year,month).wday, *1..days_in_month(year,month)]
arr.each_slice(7) { |week|
week.each { |d| print d.to_s.rjust(DAY_WIDTH) }; puts }
end
def days_in_month(year,month)
(((month==12) ? Date.new(year+1,1) : Date.new(year,month+1)) -
Date.new(year,month))
end
[编辑:在他的回答here中,@ spickerman表达了当月的天数:Date.new(year,month,-1).day
。更好,是吗?]
<强>实施例强>
calendar(2015, 2)
February, 2015
Sun Mon Tue Wed Thu Fri Sat
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
calendar(2015, 4)
April, 2015
Sun Mon Tue Wed Thu Fri Sat
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
calendar(2016, 2)
February, 2016
Sun Mon Tue Wed Thu Fri Sat
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
<强>解释强>
考虑第二个例子:
year = 2015
month = 4
首先打印标题:
title = "#{Date::MONTHNAMES[month]}, #{year}".center(7*DAY_WIDTH)
#=> "April, 2015".center(28)
#=> " April, 2015 "
puts "\n#{title}"
接下来打印星期几标题:
Date::ABBR_DAYNAMES.each { |s| print s.rjust(DAY_WIDTH) }
#=> ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"].each { |s|
#=> print s.rjust(4) }
# Sun Mon Tue Wed Thu Fri Sat
例如,"Sun".rjust(4)" #=> " Sun"
。
现在我们需要打印每周的日子。我分两步完成了这项工作:首先创建一个要打印的数组天数,包括第一周的0-6
个空格,然后打印每组七个元素:
arr = [*[' ']*Date.new(year,month).wday, *1..days_in_month(year,month)]
#=> arr = [*[' ']*3, *1..30]
#=> arr = [*[' ', ' ', ' '], *1..30]
#=> [" ", " ", " ", 1, 2,..., 30]
我们现在将arr
分成七个一组并打印每个:
arr.each_slice(7) { |week|
week.each { |d| print d.to_s.rjust(DAY_WIDTH) }; puts }
例如:
' '.to_s.d.to_s.rjust(4)
#=> ' '
10.to_s.rjust(4)
#=> ' 10'
2015年4月的天数计算如下:
(((month==12) ? Date.new(year+1,1) : Date.new(year,month+1))-
Date.new(year,month))
#=> (((4==12) ? Date.new(2016,1) : Date.new(2015,5))-Date.new(2015,4)
#=> Date.new(2015,5) - Date.new(2015,4)
#=> #<Date: 2015-05-01 ((2457144j,0s,0n),+0s,2299161j)> -
#<Date: 2015-04-01 ((2457114j,0s,0n),+0s,2299161j)>
#=> (30/1), a rational number equal to 30
答案 1 :(得分:0)
您只是忘了在日期中添加空格和换行符。尝试使用这样的东西:
def to_s
weekdays = "Su Mo Tu We Th Fr Sa"
month = "#{month_names} #{year}"
output = [
month.center(weekdays.size),
weekdays
].join("\n")
output << "\n"
i = 0
(1..length).each do |day|
i += 1
output << day.to_s
if day.to_s.length == 1
output << ' '
else
output << ' '
end
if i == 7
i = 0
output << "\n"
end
end
output
end
我添加了第一个if
语句来处理单个长度(1-9)日期&#39;间隔,第二个是每周后处理换行符(\n
)。
以:
运行Month.new(1, 2017).to_s
您的输出将是:
January 2017
Su Mo Tu We Th Fr Sa
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
此外,在旁注中,不要忘记闰年(2月有29天)。
答案 2 :(得分:0)
如果你不关心周日没有开始的月份(就像你在this comment中提到的那样),你可以这样做:
def to_s
wdays = "Su Mo Tu We Th Fr Sa"
month = "#{month_names} #{year}"
output = [ month.center(wdays.size), wdays]
(1..length).each_slice(7) do |week|
output << week.map { |day| day.to_s.rjust(2) }.join(' ')
end
output.join("\n")
end
使用each_slice(7)
将所有31天的阵列切片为7天(一周)的子阵列。调用map
将子数组中的每一天先转换为字符串(to_s
),然后再确保处理单个数字的对齐(rjust(2)
)。使用单个空格加入一周内的所有日子。