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