シェルスクリプトで指定した月の第何何曜日を取得する

いい感じで家でお酒飲んでて、ゴミ出しの日を意識してふと思い立ち、指定した日の第何何曜日(第3水曜とか、第4金曜とか…)をbashで取得出来ないかなと思ったのでやってみた。
ncalとかあると一行で取得出来そうだったけど、手元のCentOS 7だと入ってなかったのでそれを使わずに出来ないか調べた。

で、dateコマンドのみでで上手く出せれば良かったんだけど、少し目論見が外れてしまった。
「-d」で月初日と次の曜日を同時に指定できればよかったんだけど…

[root@test-centos7 ~]# date
2015年 11月 27日 金曜日 00:20:52 JST
[root@test-centos7 ~]#
[root@test-centos7 ~]# date -d '1 monday'
2015年 11月 30日 月曜日 00:00:00 JST
[root@test-centos7 ~]#
[root@test-centos7 ~]# date -d '2 monday'
2015年 12月  7日 月曜日 00:00:00 JST
[root@test-centos7 ~]#
[root@test-centos7 ~]# date -d '2015/11/01 1 monday'
2015年 11月  1日 日曜日 00:00:00 JST
[root@test-centos7 ~]#
[root@test-centos7 ~]# date -d '1 monday 2015/11/01'
2015年 11月  1日 日曜日 00:00:00 JST
[root@test-centos7 ~]#
[root@test-centos7 ~]# date -d '2015/11/01' -d '1 monday'
2015年 11月 30日 月曜日 00:00:00 JST

とまぁ、こんな感じで思ったようには動かなかった。
なお、dateコマンドをネストしても動きは変わらずなので、dateコマンドのみでは上手くいかなそうだ。残念。

ううん、phpならstrtotimeで一発なんだけどなぁ…同じように指定すればいいかと思ったけど、そう甘くはない。
pythonにもこの辺の関数は無いっぽい…

参考:2015年12月の第2月曜日をphpで取得する

php -r 'echo date("Y/m/d\n", strtotime("Second Monday of Dec 2015"));'
[root@test-centos7 ~]# php -r 'echo date("Y/m/d\n", strtotime("Second Monday of Dec 2015"));'
2015/12/14

しょうがないので、大分出来が悪いけどやっつけでシェルスクリプトを組んでみることにした。
(使うことがあるのか不明だが)

get_weekday_of_month.sh

base="$1/01"
base_dayofweek=$( date -d $base +%w )
# 0=Sun,1=Mon,2=Tue,3=Wed,4=Thu,5=Fri,6=Sat
target_dayofweek=$2
week_no=$3

if [ $base_dayofweek="0" ]; then
    date -d "$base + $(( (7 - base_dayofweek + target_dayofweek) % 7 + 7*($week_no-1))) days"
else
    date -d "$base + $(( (7 - base_dayofweek + target_dayofweek) % 7 - 1 + 7*($week_no-1))) days"
fi

[root@test-centos7 ~]# cat /work/get_weekday_of_month.sh
base="$1/01"
base_dayofweek=$( date -d $base +%w )
# 0=Sun,1=Mon,2=Tue,3=Wed,4=Thu,5=Fri,6=Sat
target_dayofweek=$2
week_no=$3

if [ $base_dayofweek="0" ]; then
    date -d "$base + $(( (7 - base_dayofweek + target_dayofweek) % 7 + 7*($week_no-1))) days"
else
    date -d "$base + $(( (7 - base_dayofweek + target_dayofweek) % 7 - 1 + 7*($week_no-1))) days"
fi
#date -d "$base + $(( (7 - base_dayofweek + target_dayofweek) % 7 )) days"

[root@test-centos7 ~]#
[root@test-centos7 ~]# sh /work/get_weekday_of_month.sh 2015/12 1 2
2015年 12月 14日 月曜日 00:00:00 JST
[root@test-centos7 ~]#
[root@test-centos7 ~]# sh /work/get_weekday_of_month.sh 2015/10 1 2
2015年 10月 12日 月曜日 00:00:00 JST
[root@test-centos7 ~]#
[root@test-centos7 ~]# sh /work/get_weekday_of_month.sh 2015/10 3 2
2015年 10月 14日 水曜日 00:00:00 JST

…そもそも、書いてて思ったんだけどスクリプトでその辺の日程を取得する意味があったんだろうか?
使う事あるのだろうか?ゴミの日くらいしか思いつかない…