2016-05-05 5 views
1

日付の間隔に何時間あるかを計算したいと思います。例えば、夏時間のために "2014.03.29-30"は47を与えます。タイムゾーン付きの2つのtimedeltaオブジェクトの相違

私の方法は、2つの日時オブジェクトを作っている例では、以下:

datetime.datetime(2014, 3, 29, 0, 0, tzinfo=<DstTzInfo 'Europe/Budapest' LMT+1:16:00 STD>) 
datetime.datetime(2014, 3, 30, 23, 59, tzinfo=<DstTzInfo 'Europe/Budapest' LMT+1:16:00 STD>) 
return (date2-date1) + timedelta(minutes=1) 

しかし、それは正しくないである、「2日間、午前0時00分00秒」を与えます。どのようにタイムゾーンとDSTを考慮に入れたtimedeltaオブジェクトを作ることができますか?また、問題全体に対するより簡単な解決策があれば、私はそれを公開しています。

ありがとうございました!

答えて

2

UTC前、'Europe/Budapest'タイムゾーンはLMT + 1:16:00 STDでした。 現在、2016-05-05現在、'Europe/Budapest'のタイムゾーンはCET + 2:00:00 DSTです。あなたはpytzのlocalize methodを使用する場合は、pytz与えられた素朴な日時に適している'Europe/Budapest'のためにタイムゾーン(のutcoffsetとdstOffsetコピー)を選択します

:対照的に

import datetime as DT 
import pytz 

tzone = pytz.timezone('Europe/Budapest') 
date1 = tzone.localize(DT.datetime(2014, 3, 29, 0, 0), is_dst=None) 
# datetime.datetime(2014, 3, 29, 0, 0, tzinfo=<DstTzInfo 'Europe/Budapest' CET+1:00:00 STD>) 

を、あなたはdatetime.datetimeに直接tzinfo=tzoneを供給する場合には、以下のように:

wrong_date1 = datetime.datetime(2014, 3, 29, 0, 0, tzinfo=tzone) 
# datetime.datetime(2014, 3, 29, 0, 0, tzinfo=<DstTzInfo 'Europe/Budapest' LMT+1:16:00 STD>) 

次いでdatetime.datetimeが誤って非常に最初のタイムゾーンを選択し関連します'Europe/Budapest'で、それが2014-3-29で有効なタイムゾーンであったかどうかにかかわらず。

したがって

、pytzを使用して、常にナイーブ日付時刻はタイムゾーンを意識させるためにtzone.localizeを使用します(。またはなかれ、その歴史を通して同じであるタイムゾーン)tzonepytz.utcでない限り

import datetime as DT 
import pytz 
tzone = pytz.timezone('Europe/Budapest') 
date1 = tzone.localize(DT.datetime(2014, 3, 29, 0, 0), is_dst=None) 
date2 = tzone.localize(DT.datetime(2014, 3, 30, 23, 59), is_dst=None) 
print(((date2-date1) + DT.timedelta(minutes=1)).total_seconds()/3600.) 
# 47.0 

Do not use tzinfo=tzone


1901-12-13 20:45:52 UTCはどこから来ましたか?

あなたはそのtzone._utc_transition_timestzone._transition_infoプライベート属性を使用してpytzのタイムゾーンのUTCの遷移時間(および関連する遷移情報)を覗くことができます。

In [43]: [(utcdate, utcoffset, dstoffset, tzabbrev) for utcdate, (utcoffset, dstoffset, tzabbrev) in zip(tzone._utc_transition_times, tzone._transition_info)][:2] 
Out[43]: 
[(datetime.datetime(1, 1, 1, 0, 0), 
    datetime.timedelta(0, 4560), 
    datetime.timedelta(0), 
    'LMT'), 
(datetime.datetime(1901, 12, 13, 20, 45, 52), 
    datetime.timedelta(0, 3600), 
    datetime.timedelta(0), 
    'CET')] 

これは日から1-1-1 UTC1901-12-13 20:45:52 UTCに時間帯省略形がLMTであったことを示していますutcoffsetは4560秒で、1時間16分に相当します。

In [47]: print(DT.timedelta(0, 4560)) 
1:16:00 

したがって、最初のt 'Europe/Budapest'に関連付けられたimezoneはLMT+1:16:00 STDです。

+0

ありがとうございました!一つの最後のこと: 'is_dst = None'部分は何をしますか?私は間違ってそれをスキップしましたが、それはあまりにもうまくいきます。 – Rolf

+2

'is_dst = None'は夏時間が終わっているときにあいまいな時間に' AmbiguousTimeError'を発生させる 'tzone.localize'を指示します - "落ちる "と同じナイーブな時間が2回発生します。それ以外の場合は適切なことを行います。それはここで効果がないのに、良い一般的な習慣として、 "注意の豊富"から使われます。デフォルトでは、 'is_dst = False'は、' tzone.localize'が、夏時間が有効でない日時を参照すると仮定して、あいまいな時刻を解決することを意味します。 – unutbu

+0

ご理解ありがとうございます。 – Rolf

関連する問題