http://www.hatena.ne.jp/1129120181
t = Time.now.localtime yd = Time.local(t.year, 12, 31).yday if yd == 365 and t.mon == 2 then # Uruu ja nai toshi 2-gatsu answer = 4 else t2 = Time.local(t.year, t.mon, 1) if yd == 366 and t.mon == 2 then # Uruu doshi 2-gatsu if t2.wday == 0 then answer = 5 else answer = 4 end else if [4,6,9,11].include?(t.mon) then # Shou no tsuki if t2.wday == 0 or t2.wday == 6 then answer = 5 else answer = 4 end else # Dai no tsuki if [0,6,5].include?(t2.wday) then answer = 5 else answer = 4 end end end end p t,answer
まず閏年でないときの2月は必ずどの曜日も4回なので先に除外。
閏年の2月は1日が日曜日のときだけ日曜日が5回。
残りの小の月(4,6,9,11)の場合は1日が土曜か日曜の場合のみ5回日曜がある。
大の月の場合は1日が金・土・日の場合だけ5回日曜がある。
なんかwdayの処理あたりがださいか。
Date を使う(1)
require ”date” d = Date.today d -= d.day - 1; p((d...(d>>1)).find_all {|i| i.wday.zero?}.size) # => 5
Date を使う(2)
require ’date’ d = Date.new(Date.today.year, Date.today.mon, 1) ans = 0 d.upto((d >> 1) - 1){|dd| if dd.wday == 0 then ans = ans+1 end } p ans
その月の1日と最後の日までをなめて日曜ならansをカウントアップ
Date を使う(3)
#今月一日の曜日と、今月が何日まであるかで決まってしまうので最初に配列を作ってしまいます……。
require ’date’ sundays = Array.new sundays[28] = [4,4,4,4,4,4,4] sundays[29] = [5,4,4,4,4,4,4] sundays[30] = [5,4,4,4,4,4,5] sundays[31] = [5,4,4,4,4,5,5] d = Date.today y = d.year m = d.mon #一日の曜日 first = Date.new(y, m, 1).wday #次の月の一日の前の日=今月の最後の日=今月の日数 #12月なら次の年の1月ということで last = (Date.new(y + (m == 12 ? 1 : 0), (m == 12 ? 1 : m + 1), 1) - 1).day p sundays[last][first] __END__
無駄なサイズの配列を作っているので、
sundays[0] = [4,4,4,4,4,4,4] sundays[1] = [5,4,4,4,4,4,4] sundays[2] = [5,4,4,4,4,4,5] sundays[3] = [5,4,4,4,4,5,5] : : p sundays[last-28][first]
が正当でしょうけど。
Date を使う(4)
歴週を使ってみました。少しトリッキーですが、ちゃんと動作すると思います。
コメントを外すとコマンドラインから任意の年と月が指定できます。
require ’date’ first_day = Date.new(Date.today.year,Date.today.mon) #first_day = Date.new(ARGV.shift.to_i,ARGV.shift.to_i) if ARGV.size == 2 p (53 + (first_day >> 1).cweek - first_day.cweek) % 53
Date を使う(5)
require ’date’ d=Date.today d-=d.day-1 p ((d>>1)-d+d.cwday-1).to_i/7
今月の日数を7で割るのが基本的なアイデアです。
月の最初の曜日に応じて適当に補正しています。
Date を使う(6)
今度はRubyで。
def countSundays(m,y) require’date’;d=Date.new(y,m);(d.cwday+((d>>1)-1).day-1)/7 end
上の方も「今月一日の曜日と、今月が何日まであるかで決まってしまう」
と言われていますが、同じ考え方です。
(1) Date#cwdayメソッドで月初の曜日を算出
(2) その値に今月の日数-1を加算
(3) (2)を7で割って商(整数)を算出
Date#cwdayメソッドの返す値の仕様(1-7,日曜=7)から、
(2)の値を7で割り切れる整数の数=日曜日の回数だと考えます。
web 上カレンダーを利用
require ’open-uri’ puts open(’http://d.hatena.ne.jp/sample/’).read.scan(%r{<tr>¥r?¥n.+?class=”calendar-day”>(¥d+)</td>}).size
こんなんどうでしょう。
すでにある資産(web上のカレンダー)を活用します。
一般化
http://www.rubyist.net/~nobu/t/20051013.html#p01
「今月」と「日曜日」を一般化するとこうかな。
require 'date' class Date def count_wdays(w) last = (self.class.new(year, month) >> 1) - 1 (last.day + (w - last.wday - 1) % 7) / 7 end end
Python
from datetime import date import calendar today = date.today() answer = 0 for i in calendar.monthcalendar(today.year, today.month): if i[6]: answer += 1 print answer
pythonのcalendar.monthcalendarは、1週間ごとの日付の配列を1ヶ月分返します。
例えば、今月なら、[[0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0]]
こんな感じ。forで1週間ごと取り出して、6番めの値が0以外なら、
日曜が存在するので1加算する、といった方法で求めています。
Perl
$ perl -MCalendar::Simple -e ’print scalar grep { $_->[0] } calendar;’
Shell
bash-3.00$ cal | cut -b 1-2 | grep -c [0-9] 5
via: A Strolling Programmer (2005-10-13)
http://www.rubyist.net/~nobu/t/20051013.html#p01