こちらで指定する4桁の日付の記載方法から、存在している日付かどうかをチェックをしたいです。

例えば8月23日だったら0823のような感じで、こちらは実際に存在している日付なのですが、9999のような実際にありえない日付だった場合、エラーを出すようにしたいです。  
4桁と数字のチェックから、4桁の数字が存在する日付なのかをチェックするにはどのようにすればいいかご教授いただければ幸いです。

```

    time=input("日付を入力をしてください：")
    if len(time)==4 :
        if time.isdigit()==True:
            print("正常")
        else:
            print("数字ではありません")
    else:
        print("桁数が違います")
    
```
CC BY-SA 4.0
2022-08-23T02:48:31.337
90703
2022-08-23T09:46:24.107
2022-08-23T09:00:17.053
3060
54115
question
python python3
入力された日付が正しいものかチェックするには？
こんな風に考えられます。

  * 最初に1月から12月までの各月の最終日(日数)が何かをリストに初期化定義しておく
  * "年"が指定されないので2月29日は何時でも有効とする
  * 現在`print("正常")`している部分を以下の処理に置き換える 
    * 入力した文字列を2桁づつ切り出して月と日をあらわす整数の変数に変換する
    * 月が1以上12以下かつ日が1以上で(最初に定義しておいたリストの)該当月の最終日以下であれば"正常"、それ以外は"月日では無い"等の文言で異常と表示する
CC BY-SA 4.0
2022-08-23T03:21:52.470
90704
2022-08-23T03:28:43.783
2022-08-23T03:28:43.783
26370
26370
90703
answer
"python date validation" で google 検索すると、例えば以下のページがヒットします。

[How do I validate a date string format in python? - Stack
Overflow](https://stackoverflow.com/q/16870663/2322778)

[回答の一つ](https://stackoverflow.com/a/16870690/2322778) を参考にすると、datetime
モジュールを使った以下のような方法が紹介されています。

>
```

>     from datetime import datetime
>  
>     datetime.strptime(date_string, "%Y-%m-%d")
>  
```

もし不正な日付が指定された場合は `ValueError` が発生するので、`try` と `expect` を使って例外処理を書いてやればよさそうです。

今回の質問の例に当てはめるなら、日付のフォーマット指定の部分は以下の様になります。

```

    datetime.strptime(date_string, "%m%d")
    
```
CC BY-SA 4.0
2022-08-23T04:19:30.263
90706
2022-08-23T04:19:30.263
3060
90703
answer
変則的なコードですが、正規表現で妥当性チェックする方法もあります。  
下記のコードでは、`is_date`関数に文字列を渡すと、4桁の月日文字列(うるう年の"0229"を含む)ならばTrueを返します。

```

    import re
    
    def is_date(s: str) -> bool:
        pattern = re.compile("(01|03|05|07|08|10|12)(0[1-9]|[12][0-9]|3[01])$|"  # 31日までの月 \
                             "(04|06|09|11)(0[1-9]|[12][0-9]|30)$|"              # 30日までの月 \
                             "(02(0[1-9]|[12][0-9]))$")                          # 29日までの月
        return pattern.match(s) != None
    
    # 正常データ
    assert is_date("0101")
    assert is_date("0229")
    assert is_date("0430")
    assert is_date("1231")
    
    # 異常データ
    assert is_date("0000") == False
    assert is_date("0132") == False
    assert is_date("0230") == False
    assert is_date("1301") == False
    assert is_date("9999") == False
    assert is_date("101") == False
    assert is_date("01011") == False
    assert is_date("OIOI") == False
    
```

**参考資料**

[yyyymmdd形式日付文字列の妥当性をチェックする正規表現を読み解く](https://qiita.com/shojit/items/c633a329dbbcc56923d6)
CC BY-SA 4.0
2022-08-23T08:05:08.793
90716
2022-08-23T08:05:08.793
9820
90703
answer
以下は Pandas モジュールの `to_datetime()` を使う方法です。

```

    import pandas as pd
    
    def validate_date_string(date_str):
        return len(date_str) == 4 and \
               pd.to_datetime(f'2000{date_str}', format='%Y%m%d', errors='coerce') is not pd.NaT
    
    if __name__ == '__main__':
        testing = ['0801', '0229', '9999', '', 'abcd']
        for t in testing:
            print(validate_date_string(t))
    
```
CC BY-SA 4.0
2022-08-23T09:46:24.107
90719
2022-08-23T09:46:24.107
47127
90703
answer