2018/11/30
[Python] datetime のコンストラクタでタイムゾーンは指定しない方がよい
以下を見てください。 日本のタイムゾーンが `+9:19` になってしまいました。 ```python >>> import datetime, pytz >>> datetime.datetime(2018, 9, 1, tzinfo=pytz.timezone('Asia/Tokyo')) datetime.datetime(2018, 9, 1, 0, 0, tzinfo=) ``` 調べてみると、pytz 2017.2 以降を使う場合、上記のような動作になるようです。 原因については、以下のコメント欄が参考になります。(以下の記事で触れているのは `replace` でタイムゾーン指定した場合ですが、コンストラクタで指定した場合も同様) > 参考 > > [pytzの仕様が変わっている - Qiita](https://qiita.com/higitune/items/0ca244373d380cf1c060) 簡単に言うと、「複数のタイムゾーン(UTC オフセット)を持つエリアでは、日付が決まらないとオフセットが決定できないので、 勝手にデフォルトのオフセットが採用される」ということのようです。 一般的に「複数のタイムゾーンを持つエリア」といえば、サマータイムがあるようなエリアで、日本は当てはまらない気がします。 ところが、日本は 1887年以前は今とは異なるタイムゾーン (`+09:18:59` ) だったそうです。 > 参考 > > [一行入魂 PostgreSQLのtime zoneについて](http://aoyagikouhei.blog8.fc2.com/blog-entry-61.html) pytz 2017.2 以降はこれを厳密に守るようになったということみたいですね 。 というわけで、aware な datetime オブジェクトを作成するには、 一度 native で作成してから aware に変換するのが正しいやり方のようです。 ```python >>> import datetime, pytz >>> dt = datetime.datetime(2018, 9, 1) >>> pytz.timezone('Asia/Tokyo').localize(dt) datetime.datetime(2018, 9, 1, 0, 0, tzinfo=) ``` 今回、たまたま日本のタイムゾーンで問題が起こって調べましたが、他のタイムゾーン では同じ問題が前からあったということですね 。