前回の回答 のコードに曜日を求めるメソッドを追加してみました。
計算方法は、 1900年1月1日からの経過日を求め、それの 7 での剰余を求めて 1900年1月1日 の曜日からのズレから曜日を元まえるととしました。
... ツェラーの公式という便利なものがあるので、それを用いています。...
という方法もありますが、今回はそれは使わずに。
2 つのコードがあります。
utils.rb
utils_test.rb
utils.rb
lang
1# coding: utf-8
2
3# 便利メソッドを定義する。
4module Utils
5  # 閏年でないときの各月の日数
6  NORMAL_DAYS_OF_MINTH = {
7    1 => 31, 2 => 28, 3 => 31,  4 => 30,  5 => 31,  6 => 30,
8    7 => 31, 8 => 31, 9 => 30, 10 => 31, 11 => 30, 12 => 31
9  }.freeze
10
11  # year 年 month 月の日数を求める
12  def days(year, month)
13    check_year_month(year, month) # year, month の値範囲をチェックする。
14
15    # 閏年の2月は 29 日まである。
16    if month == 2 && leap?(year)
17      29
18    else
19      NORMAL_DAYS_OF_MINTH[month]
20    end
21  end
22
23  # 曜日の名前
24  WEEK_NAME = %w[日 月 火 水 木 金 土]
25
26  # 曜日を求める
27  def wday(year, month, day)
28    # 1900-01-01 は月曜
29    past_days(year, month, day) % 7
30  end
31
32  # 1900-01-01 からの経過日数を得る
33  def past_days(year, month, day)
34    ans = 0
35    (1...year).each do |y|
36      ans += 365
37      ans += 1 if leap?(y)
38    end
39    (1...month).each do |m|
40      ans += days(year, m)
41    end
42    ans += day
43    ans
44  end
45
46  # year が閏年かを調べる。
47  def leap?(year)
48    (year % 4 == 0) && ((year % 400 == 0) || (year % 100 != 0))
49  end
50
51  # year, month の値範囲をチェックする。
52  def check_year_month(year, month)
53    if (year < 1900) || (2038 < year) || (month < 1) || (12 < month)
54      throw ArgumentError.new("#{year}, #{month}")
55    end
56  end
57end
58
59# --- End of File ---
utils_test.rb
lang
1 coding: utf-8
2
3require 'date'
4require File.join(File.expand_path(File.dirname(__FILE__)), 'utils.rb')
5
6#--------- test ------
7include Utils
8
9TESTS = [
10  [2000, 1, 31],
11  [2000, 2, 29],
12  [2000, 3, 31],
13  [2000, 4, 30],
14  [2000, 5, 31],
15  [2000, 6, 30],
16  [2000, 7, 31],
17  [2000, 8, 31],
18  [2000, 9, 30],
19  [2000, 10, 31],
20  [2000, 11, 30],
21  [2000, 12, 31],
22
23  [2001, 1,  31],
24  [2001, 2,  28],
25  [2001, 3,  31],
26  [2001, 4,  30],
27  [2001, 5,  31],
28  [2001, 6,  30],
29  [2001, 7,  31],
30  [2001, 8,  31],
31  [2001, 9,  30],
32  [2001, 10, 31],
33  [2001, 11, 30],
34  [2001, 12, 31]
35]
36
37TESTS.each do |t|
38  ans = Utils.days t[0], t[1]
39  fail "#{t.join(' ')} != #{t[0]} #{t[1]} #{ans}" unless ans == t[2]
40end
41
42ERR_TESTS = [
43  [nil, nil,   "undefined method `<' for nil:NilClass"],
44  [2000, nil,  "undefined method `<' for nil:NilClass"],
45  [nil, 1,     "undefined method `<' for nil:NilClass"],
46
47  [1899, 12,   'uncaught throw #<ArgumentError: 1899, 12>'],
48  [2039, 1,    'uncaught throw #<ArgumentError: 2039, 1>'],
49
50  [2000, 0,    'uncaught throw #<ArgumentError: 2000, 0>'],
51  [2000, 13,   'uncaught throw #<ArgumentError: 2000, 13>']
52]
53
54ERR_TESTS.each do |t|
55  begin
56    Utils.days t[0], t[1]
57    fail 'エラーが発生しませんでした。'
58  rescue => ex
59    raise ex.to_s + t.join(' ') if ex.to_s != t[2]
60  end
61end
62
63# Date のメソッドと結果を比較する。
64(1900..2038).each do |y|
65  #   うるう年の判定
66  fail "fail leap(#{y})"   unless Utils.leap?(y) == Date.new(y).leap?
67
68  # 月の日数
69  (1..12).each do |m|
70    fail "fail days(#{y}, #{m})"  unless Utils.days(y, m) == ((Date.new(y, m, -1) - Date.new(y, m, 1)).to_i + 1)
71    # 曜日
72    (1..8).each do |d|
73      fail "fail wday(#{y}, #{m}, #{d})"  unless Utils.wday(y, m, d) == Date.new(y, m, d).wday
74    end
75  end
76end
77
78today = Date.today
79puts "#{today} は #{WEEK_NAME[Utils.wday(today.year, today.month, today.day)]} 曜日です。"
80
81# $ rubocop days.rb
82# $ ruby days_test.rb
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。