web-dev-qa-db-ja.com

Python pytz timezone関数は、9分ずれたタイムゾーンを返します

次のコードから、まだ理解できていない何らかの理由で:

_>>> from pytz import timezone
>>> timezone('America/Chicago')
_

私は得ます:

_<DstTzInfo 'America/Chicago' LMT-1 day, 18:09:00 STD>
_

私が仮定すると、私は次のようになるはずです:

_<DstTzInfo 'America/Chicago' LMT-1 day, 18:00:00 STD>
_

...自分のタイムゾーンがUTCから6時間9分離れているとは思わないからです。

pytzのソースコード を確認しましたが、何が問題なのかを正確に把握できていなかったことを認めます。

他の値をtimezone()関数に渡しましたが、それが返す値は正しいようです。しかし、何らかの理由で、私のタイムゾーンに関連する情報が正しくありません。

最後に、隣のキューブにいる同僚が、関数が自分のマシンに正しいタイムゾーン情報を返すことを確認しました。

私のタイムゾーン(_'America/Chicago'_)が9分ずれている理由を誰かが知っていますか? pytzを使用してインストールされたpipのバージョン_2015.7_を実行しています。ありがとうございました!

21
elethan

ローカルタイムゾーンに固定UTCオフセットがない限り、特定の日時を指定せずに特定の値について話すのは無意味です。

現在の時刻などの時刻を指定すると、pytzが予想されるUTCオフセットを生成することがわかります。

>>> from datetime import datetime
>>> import pytz
>>> datetime.now(pytz.timezone('America/Chicago')).strftime('%Z%z')
'CST-0600'

見る

特定の日付/時刻を指定しない場合、pytzは、指定されたタイムゾーンで使用可能なutcオフセットのセットから任意のutcオフセットを返す場合があります。最近のpytzバージョンは、最も早い時間(原則としてLMT)に対応するutcオフセットを返しますが、これに依存しないでください。あなたとあなたの友人は、結果の違いを説明するかもしれない異なるpytzバージョンを使うかもしれません。

3
jfs

Google Groups Answer のカールマイヤーの回答に基づく回答

この違いの理由は、これはタイムゾーンにとらわれない日時オブジェクトをタイムゾーン対応オブジェクトに変換する正しい方法ではないためです。

説明は:

「pytzタイムゾーンクラスは、UTCからの単一のオフセットを表すのではなく、歴史上、おそらくいくつかの異なるUTCオフセットを経た地理的領域を表します。特定のゾーンの最も古いオフセットは、以前の時間からのオフセットを表しますゾーンは標準化されました(1800年代後半、ほとんどの場所)は通常「LMT(現地平均時間)」と呼ばれ、UTCから奇数分オフセットされることがよくあります。

(Googleグループの引用された回答からの引用)

基本的に、次のことを行う必要があります。

from datetime import datetime
import pytz

my_datetime = datetime(2015, 6, 11, 13, 30)
my_tz = pytz.timezone('America/Chicago')    
good_dt = my_tz.localize(my_datetime)

print(good_dt)

out: 2015-06-11 13:30:00-05:00

14
learn2day

私の好奇心が完全に満たされていないからといって、最近この問題をもう少し掘り下げました。

最初は、pytzのバージョンが異なるために違いが生じたようです。ただし、pytzのバージョンを、自分のマシンとは異なる結果が得られることを確認したバージョンにダウングレードした後、これが問題の原因ではないことがわかりました。同じバージョンでもof pytz私のマシンはLMTに基づくUTCオフセットを使用しているようですが、他のマシンはCDTまたはCSTに基づくオフセットを使用していました。

@ J.F。Sebastianとの会話に基づいて、他に可能性のある唯一の可能性はシステムレベルの違いであると想定しました。私はpytzソースコードをもう少し詳しく調べたところ、pytzが少なくともタイムゾーン情報の一部を取得するファイルが/usr/share/zoneinfo/。それで、ファイル/usr/share/zoneinfo/America/Chicagoおよびバイナリファイルですが、一部は読み取り可能です。ファイルの途中にタイムゾーンのリストがあります:LMTCDTCSTESTCWTCPT。ご覧のとおり、LMTはリストの最初の名前です。@ J.F.Sebastianが示唆したように、tahtは、元の質問で説明されている状況でpytzが使用するもののようです。

これは、Ubuntu 15.10でのリストの外観です。ただし、Ubuntuの以前のバージョン(TrustyやPreciseなど)では、-609ではなく-600の結果が得られたため、同じリストはCDTCSTESTCWTCPTです。

これは多くの盲目的な探索と半分の理解から来ていることを認めますが、これは私がマシン間で見た違いを説明するものであるようです。バージョン間でzoneinfoファイルが異なる理由、およびこれらの違いがUbuntuで何を意味するかについては、私にはわかりませんが、同様に好奇心が強く、洞察に満ちた修正を受ける可能性がある人のために、私の発見を共有したいと思いました/コミュニティからの補足情報。

4
elethan

あなたが言うように、元のファイルとpytzモジュールの違いがいくつかあります:(私の場合、中央時間を使用しています)

xxxx ...... lib/python2.7/site-packages/pytz/zoneinfo/US/Central

In [66]: start = start.replace(tzinfo=central)

In [67]: start.isoformat()
Out[67]: '2018-02-26T00:00:00-05:51'

oSの標準ファイルを使用する場合(私はmac、ubuntu、centosでテストしました)

/ usr/share/zoneinfo/US/Central

mv xxxx...../lib/python2.7/site-packages/pytz/zoneinfo/US/Central xxxx...../lib/python2.7/site-packages/pytz/zoneinfo/US/Central-bak

ln -s /usr/share/zoneinfo/US/Central xxxx...../lib/python2.7/site-packages/pytz/zoneinfo/US/Central

問題は解決しました

In [7]: central = timezone('US/Central')

In [8]: central
Out[8]: <DstTzInfo 'US/Central' CST-1 day, 18:00:00 STD>

In [10]: start = start.replace(tzinfo=central)

In [11]: start.isoformat()
Out[11]: '2018-02-27T00:00:00-06:00'