pytz 本地化与日期时间替换

发布于 2024-08-04 10:19:17 字数 1046 浏览 2 评论 0原文

我在使用 pytz 的 .localize() 函数时遇到一些奇怪的问题。有时它不会对本地化日期时间进行调整:

.localize 行为:

>>> tz
<DstTzInfo 'Africa/Abidjan' LMT-1 day, 23:44:00 STD> 
>>> d
datetime.datetime(2009, 9, 2, 14, 45, 42, 91421)

>>> tz.localize(d)
datetime.datetime(2009, 9, 2, 14, 45, 42, 91421, 
                  tzinfo=<DstTzInfo 'Africa/Abidjan' GMT0:00:00 STD>)
>>> tz.normalize(tz.localize(d))
datetime.datetime(2009, 9, 2, 14, 45, 42, 91421,
                  tzinfo=<DstTzInfo 'Africa/Abidjan' GMT0:00:00 STD>)

如您所见,时间并未因本地化/规范化操作而改变。 但是,如果使用 .replace:

>>> d.replace(tzinfo=tz)
datetime.datetime(2009, 9, 2, 14, 45, 42, 91421, 
                  tzinfo=<DstTzInfo 'Africa/Abidjan' LMT-1 day, 23:44:00 STD>)
>>> tz.normalize(d.replace(tzinfo=tz))
datetime.datetime(2009, 9, 2, 15, 1, 42, 91421,
                  tzinfo=<DstTzInfo 'Africa/Abidjan' GMT0:00:00 STD>)

这似乎会对日期时间进行调整。

问题是 - 哪个是正确的,为什么其他的是错误的?

I'm having some weird issues with pytz's .localize() function. Sometimes it wouldn't make adjustments to the localized datetime:

.localize behaviour:

>>> tz
<DstTzInfo 'Africa/Abidjan' LMT-1 day, 23:44:00 STD> 
>>> d
datetime.datetime(2009, 9, 2, 14, 45, 42, 91421)

>>> tz.localize(d)
datetime.datetime(2009, 9, 2, 14, 45, 42, 91421, 
                  tzinfo=<DstTzInfo 'Africa/Abidjan' GMT0:00:00 STD>)
>>> tz.normalize(tz.localize(d))
datetime.datetime(2009, 9, 2, 14, 45, 42, 91421,
                  tzinfo=<DstTzInfo 'Africa/Abidjan' GMT0:00:00 STD>)

As you can see, time has not been changed as a result of localize/normalize operations.
However, if .replace is used:

>>> d.replace(tzinfo=tz)
datetime.datetime(2009, 9, 2, 14, 45, 42, 91421, 
                  tzinfo=<DstTzInfo 'Africa/Abidjan' LMT-1 day, 23:44:00 STD>)
>>> tz.normalize(d.replace(tzinfo=tz))
datetime.datetime(2009, 9, 2, 15, 1, 42, 91421,
                  tzinfo=<DstTzInfo 'Africa/Abidjan' GMT0:00:00 STD>)

Which seems to make adjustments into datetime.

Question is - which is correct and why other's wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

任谁 2024-08-11 10:19:17

localize 只是假设您传递给它的天真日期时间是“正确的”(除了不知道时区!),因此只设置时区,没有其他调整。

您可以(并且建议......)在 UTC 内部工作(而不是使用简单的日期时间),并在需要以本地化方式执行日期时间的 I/O 时使用 replacenormalize 将处理 DST 等)。

localize just assumes that the naive datetime you pass it is "right" (except for not knowing about the timezone!) and so just sets the timezone, no other adjustments.

You can (and it's advisable...) internally work in UTC (rather than with naive datetimes) and use replace when you need to perform I/O of datetimes in a localized way (normalize will handle DST and the like).

温柔嚣张 2024-08-11 10:19:17

localize 是用于创建具有初始固定日期时间值的日期时间感知对象的正确函数。生成的日期时间感知对象将具有原始日期时间值。在我看来,这是一种非常常见的使用模式,也许 pytz 可以更好地记录这种使用模式。

replace(tzinfo = ...) 不幸被命名。它是一个行为随机的函数。我建议避免使用此功能来设置时区,除非您喜欢自我造成的痛苦。使用这个功能我已经受够了。

localize is the correct function to use for creating datetime aware objects with an initial fixed datetime value. The resulting datetime aware object will have the original datetime value. A very common usage pattern in my view, and one that perhaps pytz can better document.

replace(tzinfo = ...) is unfortunately named. It is a function that is random in its behaviour. I would advise avoiding the use of this function to set timezones unless you enjoy self-inflicted pain. I have already suffered enough from using this function.

缪败 2024-08-11 10:19:17

此 DstTzInfo 类用于与 UTC 的偏移量在某些时间点发生变化的时区。例如(您可能知道),许多地点在夏初过渡到“夏令时”,然后在夏末过渡到“标准时间”。每个 DstTzInfo 实例仅代表这些时区之一,但“本地化”和“规范化”方法可帮助您获取正确的实例。

对于阿比让来说,只发生过一次转换(根据 pytz 的说法),那是在 1912 年:

>>> tz = pytz.timezone('Africa/Abidjan')
>>> tz._utc_transition_times
[datetime.datetime(1, 1, 1, 0, 0), datetime.datetime(1912, 1, 1, 0, 16, 8)]

我们从 pytz 中得到的 tz 对象代表 1912 年之前的时区:

>>> tz
<DstTzInfo 'Africa/Abidjan' LMT-1 day, 23:44:00 STD>

现在查看您的两个示例,看看当您调用tz.localize(d) 您没有将这个 1912 年之前的时区添加到您的幼稚日期时间对象中。它假定您提供的日期时间对象代表该当地时间的正确时区中的本地时间,即 1912 年之后的时区。

但是,在使用 d.replace(tzinfo=tz) 的第二个示例中,它使用 datetime 对象来表示 1912 年之前的时区中的时间。这可能不是你的意思。然后,当您调用 dt.normalize 时,它​​会将其转换为适合该日期时间值的时区,即 1912 年之后的时区。

This DstTzInfo class is used for timezones where the offset from UTC changes at certain points in time. For example (as you are probably aware), many locations transition to "daylight savings time" at the beginning of Summer, and then back to "standard time" at the end of Summer. Each DstTzInfo instance only represents one of these timezones, but the "localize" and "normalize" methods help you get the right instance.

For Abidjan, there has only ever been one transition (according to pytz), and that was in 1912:

>>> tz = pytz.timezone('Africa/Abidjan')
>>> tz._utc_transition_times
[datetime.datetime(1, 1, 1, 0, 0), datetime.datetime(1912, 1, 1, 0, 16, 8)]

The tz object we get out of pytz represents the pre-1912 timezone:

>>> tz
<DstTzInfo 'Africa/Abidjan' LMT-1 day, 23:44:00 STD>

Now looking up at your two examples, see that when you call tz.localize(d) you do NOT get this pre-1912 timezone added to your naive datetime object. It assumes that the datetime object you give it represents local time in the correct timezone for that local time, which is the post-1912 timezone.

However in your second example using d.replace(tzinfo=tz), it takes your datetime object to represent the time in the pre-1912 timezone. This is probably not what you meant. Then when you call dt.normalize it converts this to the timezone that is correct for that datetime value, ie the post-1912 timezone.

画骨成沙 2024-08-11 10:19:17

我意识到我在这方面有点晚了......
但这是我发现效果很好的方法。
正如 Alex 所说,在 UTC 中工作:

tz = pytz.timezone('Africa/Abidjan')
now = datetime.datetime.utcnow()

然后进行本地化:

tzoffset = tz.utcoffset(now)
mynow = now+tzoffset

并且此方法确实可以完美处理 DST

I realize I'm a little late on this...
but here is what I found to work well.
Work in UTC as Alex stated:

tz = pytz.timezone('Africa/Abidjan')
now = datetime.datetime.utcnow()

Then to localize:

tzoffset = tz.utcoffset(now)
mynow = now+tzoffset

And this method does handle DST perfectly

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文