結局第何週の何曜日かどうかの判定ってどうやんだよ！！😡💢

# はじめに

酔っぱらったパワーでこの記事を書いてます。

お酒飲みながら、出来上がったコードのリファクタとか（は？）、新規機能開発とかやってたんですけど、
第何週の何曜日っていうのをどうやって判定しよう...みたいなところで
ハマってしまってﾝﾝﾝﾝ！！ってなってしまってこの記事を書いています。

雑で申し訳ない。


# 大体なんで標準モジュールでサポートしてないのよ。

いろいろ考えたんですが、[PythonのCalendarの公式リファレンス](https://docs.python.org/ja/3/library/calendar.html)を読んでいて気づいたんですよね。
そもそも、カレンダーにはスタートの曜日がどこか問題みたいなのがあるみたいで、
特にカレンダーとかだとアメリカ式・ヨーロッパ式・中東式と国によって結構違うってことを知りました。
(参考文献:[１週間のはじまりは何曜日？アメリカ式とヨーロッパ式って？](ayasato-boueki.com/2017/11/calendar.html))

ちなみに、ヨーロッパ式(日曜始まり)の日本でもお馴染みの形式がISO準拠しているので、
日曜始まりが国際標準なんだとか。（ほーん。。。）

まぁでも、`calendar`モジュールには始まりを指定できるやつもあるし、ありそうなんだけどなぁーと...

...いや、肝心なことに気が付いた、そもそも第2水曜日とかって言う概念、*2つの意味*があるぞ??

# 第２水曜日の意味は二つ存在する問題

<img width="400" alt="スクリーンショット 2020-05-30 23.30.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182970/accb6a14-c872-5c57-5ed3-97db47ad35c7.png">


例えば、木曜始まりの月があって、その次の週の水曜日ってなんて言うと思います？？

### あれ？これって第2水曜日なの？第１水曜日なの？
正確な言い方をするとこれは、

### 第2週目の第1水曜日

ですよね。

もう酔っ払って訳わからなくなったので、ググって、一番上のページに答えが載っていました。

[第何何曜日という数え方について](https://week2017.xyz/you/reference.html)

これによると、日本の法律上の「国民の祝日」に対して定義している第何何曜日は、
> この日時表記法の正しい理解の仕方について簡潔に書きます。日本の法律で定められている「国民の祝日」も、この数え方です。
1日から7日は「第一何曜日」
8日から14日は「第二何曜日」
15日から21日は「第三何曜日」
22日から28日は「第四何曜日」
29日以降は「第五何曜日」となります。
つまりその月の１日から７日までの期間に存在する日曜日が「第一日曜日」。

めっちゃ納得しました！！これでゴミの日通知の実装に困りそうにありませんね！

# つまり、地域によって変わりそうだから実装してないんだよねって話

だから`calendar`モジュールになかった訳ですな...納得。


# しょうがないから、使えそうな物を集める

まず、`datetime`モジュールに`date.weekday()`関数を使えば曜日がわかると言うことを発見した。
オッケ！これ使えばええやん！
(参考文献：[datetime --- 基本的な日付型および時間型 date.weekday()](https://docs.python.org/ja/3/library/datetime.html#datetime.date.weekday))

ん、ちょっと待って？

### 先発、先発グレゴリオ暦って何？

ってか、その先にさらに、**ISO暦**なる物が出てきてなんじゃこりゃ...

いろいろ調べて見て、「[datetimeで定義される「先発グレゴリオ暦」について](https://qiita.com/HidKamiya/items/566faeab829be897a50c)」なるQiita記事を発見。
詳細はこちらを読んで欲しい。とりあえずもう私の判断能力を超えてきた。

### とりあえず、カレンダーって沼だな！！

結論から言うと、希望する物を公式が実装しようにも、マサカリが山ほど飛んできそうな事態は把握した。おk。

# 実装はこちら。

```{python:第何何曜日か聞くコード}
import datetime
def numOfWeek(today: datetime.date) ->int :
    return (today.day-1)//7 + 1
```

テストコード含む全体はこちら

```{python:テストコード}
import datetime
def numOfWeek(today: datetime.date) ->int :
    return (today.day-1)//7 + 1
    
test1 = datetime.date(2020,5,31)
test2 = datetime.date(2020,6,1)
test3 = datetime.date(2020,7,23)

test = [test1,test2,test3]
weekday = "月火水木金土日"
for t in test:
    print(t,"は第",numOfWeek(t),weekday[t.weekday()],"曜日です。")
```
```
2020-05-31 は第 5 日 曜日です。
2020-06-01 は第 1 月 曜日です。
2020-07-23 は第 4 木 曜日です。
```

# おわりに

なんか、酔いが覚めてからこの記事見直したんですけど、結構、あたり前体操〜〜って感じで、
恥ずかしくなってきました。慰めにLGTMください😭


# おまけ。

タイトル通りのことしようと思って、気軽に**何週目の**何曜日を出力するためのコードを書いてみました

## 実装

```{python:何週目の何曜日か判別するコード}
import datetime
import calendar
calendar.setfirstweekday(6)

def numberOfWeek(today: datetime.date) -> int:
    calendar_list=calendar.monthcalendar(today.year, today.month)
    for x,(week) in enumerate(calendar_list):
        if today.day in week:
            return x+1


test1 = datetime.date(2020,5,31)
test2 = datetime.date(2020,6,1)
test3 = datetime.date(2020,7,23)

test = [test1,test2,test3]
weekday = "月火水木金土日"
for t in test:
    print(t,"は第",numberOfWeek(t),"週",weekday[t.weekday()],"曜日です。")
    
```
```{:結果}
2020-05-31 は第 6 週 日 曜日です。
2020-06-01 は第 1 週 月 曜日です。
2020-07-23 は第 4 週 木 曜日です。
```
欲しい人はまるっとコピーしてもらって大丈夫です。