使用pytz的python时区转换问题

Posted

技术标签:

【中文标题】使用pytz的python时区转换问题【英文标题】:python timezone conversion issues using pytz 【发布时间】:2015-06-13 12:21:29 【问题描述】:

我正在使用 pytz 进行日期时间转换,但在大约 8 AM EST DST 活动的情况下,pytz 会显示意外数据。

eight_35 = datetime.now(pytz.timezone('US/Eastern')) # assume today's 8:35AM EST
eight_am = datetime(eight_35.year, eight_35.month, eight_35.day, 8, 0, 0, 0, tzinfo=pytz.timezone('US/Eastern'))

我注意到虽然eight_35tzinfo=<DstTzInfo 'US/Eastern' EDT-1 day, 20:00:00 DST>eight_amtzinfo=<DstTzInfo 'US/Eastern' LMT-1 day, 19:04:00 STD>,但我不确定哪个是正确的。

如果我转换为 UTC,我会得到以下结果:

eight_35.astimezone(pytz.utc) >>> 12:35PM UTC
eight_am.astimezone(pytz.utc) >>> 12:56PM UTC

我的代码应该检查用户是否已经在美国东部标准时间上午 8 点之后登录。 Django 在创建查询集时会自动转换为 UTC。

UserLoginLog.objects.create(user=user, date_login=now) date logged is 12:35PM UTC

# this will result in no items because eight_am is translated as 12:56PM
UserLoginLog.objects.filter(user=user, date_login__gte=eight_am)

如您所见,用户在上午 8 点 35 分登录,所以如果我在上午 8 点之后获得所有日志 处理它的最佳方法是什么,以便我可以检测夏令时但仍然能够准确地比较数据?

【问题讨论】:

您可能会发现Problems with Localtime 很有帮助;它解释了为什么直接指定 tzinfo 有时不起作用,以及如何使用 localize 解决问题。 您需要本地化或规范化日期时间。仅仅因为当您有一个幼稚的日期时间并应用时区时,此时没有关于夏令时的信息。一般来说,从本地datetime 转换为UTC 可能有两个结果。因此,正如@unutbu 评论的那样,在将时区应用于天真的datetime 时,仅使用localize 【参考方案1】: datetime.now(pytz.timezone('US/Eastern'))——正确 datetime(..same time.., tzinfo=pytz.timezone('US/Eastern')) -- 不正确

请参阅this answer,了解为什么不应将tzinfo 参数与可能在不同时间具有不同UTC 偏移量的pytz 时区一起使用。

.now(tz) 在内部使用 UTC 时间 (tz.fromutc(utc_time)),因此它允许时区选择与给定时间对应的正确 UTC 偏移量。

如果您更改了一个可感知的日期时间对象(以便生成的时间可能具有不同的 UTC 偏移量),那么您应该调用 dt = tz.normalize(dt) 以获取正确的 tzinfo。见Localized times and date arithmetic。

【讨论】:

【参考方案2】:

你们都很有帮助!所以我所做的就是制作类似的东西

@staticmethod
def est_localize(datetime_object):
    # remove tzinfo
    new_datetime = datetime_object.replace(tzinfo=None)
    # finally, localize the datetime
    new_datetime = pytz.timezone('US/Eastern').localize(new_datetime)
    return new_datetime

我创建的每个日期时间对象,我将它们全部包装在est_localize() 中,包括我必须使用+timedelta()+relativedelta() 的对象。只要我将它们包裹在est_localize() 中,所有内容都会被正确翻译。谢谢大家!

eight_35 = datetime.now(pytz.timezone('US/Eastern')) # assume today's 8:35AM EST
eight_am = est_localize(datetime(eight_35.year, eight_35.month, eight_35.day, 8))

【讨论】:

以上是关于使用pytz的python时区转换问题的主要内容,如果未能解决你的问题,请参考以下文章

python模块-pytz时区转换

python 使用`pytz`将时间和日期对话转换为其他时区。

Python pytz 将时间戳(字符串格式)从一个时区转换为另一个时区

Pytz Python时区转换不起作用

python 通过pytz模块进行时区的转换,获取指定时区的时间

在 Python 3 的 Pytz 模块中将 EST、CST 和 DST 时区转换为 unix 时间戳