gpt4 book ai didi

python夏令时问题

转载 作者:太空宇宙 更新时间:2023-11-03 15:11:44 25 4
gpt4 key购买 nike

我在夏令时方面遇到问题。

让我解释一下上下文。

我将 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

更新:解决方案

Christian 的解决方案 1

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

最佳答案

我在扩展 vevents 的重复规则时遇到了与 dateutil 的 rrule 类似的问题。对我有用的是保存时区信息,然后将每个日期时间对象转换为原始日期时间对象,进行计算,然后使用保存的时区本地化每个日期时间。

所以按照这些思路:

orig_tz = dt.tzinfo
dt = dt.replace(tzinfo=None)

# do calculations here

orig_tz.localize(dt)

关于python夏令时问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25715276/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com