我有一个没有时区信息的datetime
对象。现在我获取了时区信息,想把时区信息加入到已存在的datetime
实例中,应该怎么办?
d = datetime.datetime.now()
tz = pytz.timezone('Asia/Taipei')
如何将时区信息tz
添加到日期时间a
中
使用 tz.localize(d)
将实例本地化。来自文档:
第一种方法是使用 pytz 库提供的 localize() 方法。这用于将无时区信息的 naive datetime(datetime)本地化:
如果您不使用`tz.localize()`,而是使用`datetime.replace()`,则很有可能会使用历史偏移量。`tz.localize()`将选择对于给定日期有效的正确偏移量。例如,美国东部时区的夏令时开始和结束日期随时间改变。
>>> loc_dt = eastern.localize(datetime(2002, 10, 27, 6, 0, 0)) >>> print(loc_dt.strftime(fmt)) 2002-10-27 06:00:00 EST-0500
当您尝试本地化一个日期时间值时,如果该值跨越了夏令时与冬令时转换期间,时区将被咨询以确定结果日期时间对象是否应该返回True或False的`.dst()`。您可以使用`.localize()`的`is_dst`关键字参数覆盖时区的默认设置。
dt = tz.localize(naive, is_dst=True)
通过设置
is_dst=None
,甚至可以完全关闭选择。在这种情况下,或者在极少数情况下没有为时区设置默认值的情况下,模糊的日期时间值将导致引发AmbiguousTimeError
异常。只有模糊的日期时间值才会查询is_dst
标志,否则会被忽略。要将时区感知对象转换回本地时间对象,请使用
.replace(tzinfo=None)
:
naivedt = awaredt.replace(tzinfo=None)
如果您知道原始日期时间是在您正在尝试添加到的时区中“测量”的,那么您可以(但可能不应该)使用replace
而不是localize
。
# d = datetime.datetime.now()
# tz = pytz.timezone('Asia/Taipei')
d = d.replace(tzinfo=tz)
我能想象出两种情况下这么做会有意义(第二种情况正是我遇到的):
datetime
实例(并且后续将其本地化到“正确”的时区,以使now()的值与其他您要进行比较的时间(例如您的手表)相匹配)。time
实例(而不是datetime
)添加一个时区(tzinfo)属性,以便稍后可以使用该属性形成完整的datetime
实例。parse('2022-09-03 10:00').replace(tzinfo=pytz.timezone('Europe/Berlin')) - parse('2022-09-03 10:00:00+02:00')
-> datetime.timedelta(seconds=4020)
,
pytz.timezone('Europe/Berlin').localize(parse('2022-09-03 10:00')) - parse('2022-09-03 10:00:00+02:00')
-> datetime.timedelta(0)
- nuts
.replace(tzinfo=None)
方法,返回一个不带时区信息的datetime实例。 - Martijn Pieters.replace()
。我同意这通常没有意义...但是如果您告知一个带有时区的time
,那么在形成日期时间时稍后可以使用tz。 - hobs.replace()
函数替换pytz
可能具有多个 UTC 偏移量的时区是错误的(许多时区都是如此)。默认的 tzinfo 对象通常对应于 LMT(太阳时间),这在大多数情况下并不是您想要的(我认为默认值的原因是帮助揭示不正确的.replace()
使用方法)。 - jfsdatetime.time
实例,没有日期信息),这可能是可以接受的。我处理来自 wunderground.com 的 CSV 时遇到了这种情况。TZ 信息可用于列标题中(有时还在字段字符串中),但日期却可从其他地方获取。因此,我只需将时间标记为 tzinfo,并使用该 tzinfo 在稍后与日期进行本地化。我知道这是错误且不规范的方法,但它对我起作用了。对我错误答案的投票将希望鼓励其他人认真考虑如何正确解决这种边缘情况。 - hobs