ruby中当前日历月的控制台输出

mqkwyuun  于 2021-09-29  发布在  Java
关注(0)|答案(3)|浏览(284)

我需要用ruby向控制台输出当前月份的日历。结果应该类似于类unix系统上的ncal。我为c++找到了一个解决方案,但不能适应ruby。到目前为止,我只意识到我需要使用嵌套循环来输出高度和宽度。告诉我往哪个方向走?

require 'date'
days = %w[Mun Tue Wed Thu Fri Sat Sun]
puts "    #{Date::MONTHNAMES[Date.today.month]} #{Date.today.year}"
i = 0
start_month = (Date.today - Date.today.mday + 1).strftime("%a")

while i < days.size
  print days[i]
  j = 1

  while j <= 31
    if days[i] == start_month 
      print " #{j}"
    end
    j += 7
  end

  i += 1
  puts
end
oipij1gg

oipij1gg1#

到目前为止,我将介绍您的解决方案,并尝试给出一些具体的指示,说明如何处理此问题-当然,通常有许多不同的方法来处理此问题,因此这绝不是唯一的方法!
第一个关键问题(如您所知!)由于以下行,您只打印从本月1日开始的行的内容:

if days[i] == start_month

按照目前的总体设计,我们知道每行都需要打印一些内容,所以很明显,像这样的条件是行不通的。让我们试着移除它。
首先,更方便的是知道一个月从一周中的哪一天开始是一个数字,而不是一个字符串,因此我们可以轻松地计算另一天的偏移量。让我们用以下方法来实现:


# e.g. for 1st July 2021 this was a Thursday, so we get `4`.

start_of_month_weekday = (Date.today - Date.today.mday + 1).cwday

接下来(这是关键的一步!),我们可以使用上述信息来找出“现在是一个月的哪一天,在一周的这一天?”
这里是该计算的第一个版本,已纳入到您的解决方案中:

require 'date'
days = %w[Mon Tue Wed Thu Fri Sat Sun]
puts "    #{Date::MONTHNAMES[Date.today.month]} #{Date.today.year}"
i = 0

# e.g. for 1st July 2021 this was a Thursday, so we get `4`.

start_of_month_weekday = (Date.today - Date.today.mday + 1).cwday

while i < days.size
  print days[i]
  day_of_month = i - start_of_month_weekday + 2 # !!!

  while day_of_month <= 31
    print " #{day_of_month}"
    day_of_month += 7
  end

  i += 1
  puts
end

这将产生:

July 2021
Mon -2 5 12 19 26
Tue -1 6 13 20 27
Wed 0 7 14 21 28
Thu 1 8 15 22 29
Fri 2 9 16 23 30
Sat 3 10 17 24 31
Sun 4 11 18 25

不错!现在我们有进展了!
剩下的我就让你来解决了😉 .... 但以下是一些线索,供我下一步处理:
这个代码, print " #{day_of_month}" ,如果日数小于1,则需要打印“空白”。这可以通过简单的 if 陈述
类似地,由于您希望此日历在网格中整齐排列,因此需要此代码始终打印两个字符宽的日历。 sprintf 你的朋友在这里!查看“宽度示例”,大约在页面的一半。
你已经硬编码了 31 用于当月的天数。当然,这应该是固定的(使用 Date 图书馆
你用这种方式很有趣 strftime("%a") 在一个地方,却在上面一行笨拙地构建了日历标题!😄 查看文档中的日期格式;它非常灵活。我认为你可以使用: Date.today.strftime("%B %Y") .
如果你想在本月的某一天增加一些颜色(或背景颜色?),考虑这样做,或者使用一个库来帮助。
使用 while 循环可以正常工作,但它不是红色的。在99%的情况下,ruby甚至有更好的工具来完成这项工作;这是一种非常有表现力的语言——迭代器是王者(我猜你是在ruby之前第一次学习另一门语言吧?看到 while 循环,和/或 for 循环,是一个死赠品,你更熟悉另一种语言。)而不是外部的while循环( while i < days.size ),你可以用 days.each_with_index . 而不是内部while循环( while j < 31 ),你可以用 day_of_month.step(31, 7) (多酷啊!!)。

ewm0tg9j

ewm0tg9j2#

这是一种方式:
构造一个一维数组,从daynames(mon-tue…)开始。
找出一种方法来确定一个月开始时有多少个“空白”(这是上个月的天数)。 wday 可能会有帮助)。将该数量的空字符串附加到数组。
确定该月有多少天(提示 Date.new(2021,7,-1) ,并将所有这些日数附加到数组。
将空字符串附加到数组,直到数组的大小可被7整除(或者更好,计算)。如果跳过最后一个项目,请跳过此项。
将此数组的所有元素转换为大小为3或类似的右调整字符串。
使用 each_slice(7) 将阵列分为几个星期。
如果需要, transpose 此周切片数组用于模拟ncal输出。

yr9zkbsy

yr9zkbsy3#

谢谢你的帮助,大约10个小时,多亏了你,我才明白过来。对于最初提出的错误问题,我再次表示歉意。
在提示的帮助下,我组装了这样一个解决方案。

require 'date'
days = %w[Mon Tue Wed Thu Fri Sat Sun]
p days
blanks = Date.new(2021,7,1).wday - 1

blanks.times do
  days.push(' ')
end

days_in_month = Date.new(2021, 7, -1).day
days_in_month
day = 1

while day <= days_in_month
  days.push(day)
  day += 1
end 

unless (days.size % 7) == 0
 days.push(' ')
end 

days.join(', ')
new_arr = days.each_slice(7).to_a
 puts"Массив дней: #{new_arr}"

for i in 0...7

 for j in 0...new_arr.size
  print "  #{new_arr[j][i]}"
 end
puts
end

相关问题