[英]python daylight saving time issues
我在夏令時遇到麻煩。
讓我解釋一下背景。
我在我的數據庫中存儲UTC日期。 每個用戶都有一個時區,我也將這些信息存儲在數據庫中。
我根據每個用戶的時區計算“1個月”的周期。
例如,用戶應該看到:
2014-01-06 -> 2014-02-05
2014-02-06 -> 2014-03-05
2014-03-06 -> 2014-04-05
2014-04-06 -> 2014-05-05
2014-05-06 -> 2014-06-05
etc.
夏令時開啟或關閉時(3月和11月)我遇到問題
代替:
2014-03-06 -> 2014-04-05
,我得到2014-03-06 -> 2014-04-06
2014-11-06 -> 2014-12-05
,我得到2014-11-05 -> 2014-12-04
然后它是所有下一個的偏移量。
我嘗試使用UTC日期而不是將它們轉換為用戶時區以在get_end_date中添加1個月,但我仍然遇到問題。
知道如何處理這個嗎?
謝謝
這是我的代碼和get_end_date方法。
import pytz
from dateutil.parser import parse as parse_date
from dateutil.relativedelta import relativedelta
def to_tz(dt, tz):
tz = pytz.timezone(tz)
return tz.normalize(dt.astimezone(tz))
def get_end_date(dt, tz):
dt_central = to_tz(dt, tz)
# Add 1 month, set hours, minutes, seconds, microseconds to 0 and remove -1 ms
dt_central = dt_central + relativedelta(months=+1)
dt_central = dt_central.replace(hour=0, minute=0, second=0, microsecond=0)
dt_central = dt_central + relativedelta(microseconds=-1)
return to_tz(dt_central, 'UTC')
def print_periods(start_dt, tz, nb_periods=6):
for i in xrange(nb_periods):
print '\n# Period {}'.format(i+1)
end_dt = get_end_date(start_dt, tz)
start_dt_central, end_dt_central = to_tz(start_dt, tz), to_tz(end_dt, tz)
print '{} -> {}'.format(start_dt_central.date(), end_dt_central.date())
print ' > start_dt_central: ', start_dt_central
print ' > end_dt_central: ', end_dt_central
print ' > start_dt: ', start_dt
print ' > end_dt: ', end_dt
start_dt = end_dt + relativedelta(microseconds=1)
產出:
central_tz = 'US/Central'
start_dt = parse_date('2014-01-06 06:00:00+00:00')
In [7]: print_periods(start_dt, central_tz, nb_periods=12)
# Period 1
2014-01-06 -> 2014-02-05
> start_dt_central: 2014-01-06 00:00:00-06:00
> end_dt_central: 2014-02-05 23:59:59.999999-06:00
# Period 2
2014-02-06 -> 2014-03-05
> start_dt_central: 2014-02-06 00:00:00-06:00
> end_dt_central: 2014-03-05 23:59:59.999999-06:00
# Period 3
2014-03-06 -> 2014-04-06
> start_dt_central: 2014-03-06 00:00:00-06:00
> end_dt_central: 2014-04-06 00:59:59.999999-05:00
# Period 4
2014-04-06 -> 2014-05-05
> start_dt_central: 2014-04-06 01:00:00-05:00
> end_dt_central: 2014-05-05 23:59:59.999999-05:00
# Period 5
2014-05-06 -> 2014-06-05
> start_dt_central: 2014-05-06 00:00:00-05:00
> end_dt_central: 2014-06-05 23:59:59.999999-05:00
# Period 6
2014-06-06 -> 2014-07-05
> start_dt_central: 2014-06-06 00:00:00-05:00
> end_dt_central: 2014-07-05 23:59:59.999999-05:00
# Period 7
2014-07-06 -> 2014-08-05
> start_dt_central: 2014-07-06 00:00:00-05:00
> end_dt_central: 2014-08-05 23:59:59.999999-05:00
# Period 8
2014-08-06 -> 2014-09-05
> start_dt_central: 2014-08-06 00:00:00-05:00
> end_dt_central: 2014-09-05 23:59:59.999999-05:00
# Period 9
2014-09-06 -> 2014-10-05
> start_dt_central: 2014-09-06 00:00:00-05:00
> end_dt_central: 2014-10-05 23:59:59.999999-05:00
# Period 10
2014-10-06 -> 2014-11-05
> start_dt_central: 2014-10-06 00:00:00-05:00
> end_dt_central: 2014-11-05 22:59:59.999999-06:00
# Period 11
2014-11-05 -> 2014-12-04
> start_dt_central: 2014-11-05 23:00:00-06:00
> end_dt_central: 2014-12-04 23:59:59.999999-06:00
# Period 12
2014-12-05 -> 2015-01-04
> start_dt_central: 2014-12-05 00:00:00-06:00
> end_dt_central: 2015-01-04 23:59:59.999999-06:00
解決方案1來自Christian
def get_end_date(dt, tz):
dt_central = to_tz(dt, tz)
orig_tz = dt_central.tzinfo
dt_central = dt_central.replace(tzinfo=None)
# Calculations
dt_central = orig_tz.localize(dt_central)
dt_utc = to_tz(dt_central, 'UTC')
return dt_utc
我自己的解決方案2
def get_end_date(dt, tz):
dt_central = to_tz(dt, tz)
# Calculations
dt_utc = to_tz(dt_central, 'UTC')
# When switch to Daylight Saving Time
if to_tz(dt_utc, tz).hour == 0:
dt_utc = dt_utc.replace(hour=dt_utc.hour-1)
# When leave Daylight Saving Time
elif to_tz(dt_utc, tz).hour == 22:
dt_utc = dt_utc.replace(hour=dt_utc.hour+1)
return dt_utc
在擴展vevent的重現規則的同時,我遇到了與dateutil的rrule
類似的問題。 對我有用的是保存時區信息,然后將每個日期時間對象轉換為天真的日期時間對象,進行計算,然后使用保存的時區本地化每個日期時間。
所以沿着這些方向:
orig_tz = dt.tzinfo
dt = dt.replace(tzinfo=None)
# do calculations here
orig_tz.localize(dt)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.