如果我将 UTC 时间加 1 小时并进行本地化,或者将本地时间加 1 小时,为啥会有所不同?

Posted

技术标签:

【中文标题】如果我将 UTC 时间加 1 小时并进行本地化,或者将本地时间加 1 小时,为啥会有所不同?【英文标题】:Why does it make a difference if I add 1 hour to the UTC time and localize or 1 hour to the local time?如果我将 UTC 时间加 1 小时并进行本地化,或者将本地时间加 1 小时,为什么会有所不同? 【发布时间】:2018-10-30 18:59:27 【问题描述】:

示例代码

from datetime import datetime, timezone, timedelta
import pytz

t11 = datetime(1918, 4, 15, 0, 0, tzinfo=timezone.utc).astimezone(pytz.timezone('Europe/Berlin'))
t12 = t11 + timedelta(hours=1)

t2 = datetime(1918, 4, 15, 1, 0, tzinfo=timezone.utc).astimezone(pytz.timezone('Europe/Berlin'))

print(t12)
print(t2)

观察到

1918-04-15 02:00:00+01:00
1918-04-15 03:00:00+02:00

预期

我希望两者都是我看到的t2。关键的区别是t2.hourt12.hour。对于时区感知的日期时间对象,我希望小时是本地时间。

问题

如何改变这种行为?这是什么原因造成的?

【问题讨论】:

再一次,这不是关于图书馆,而是关于德国时间;那是时钟改变的时候:timeanddate.com/time/change/germany?year=1918。如果您没有在冬季/夏季时间之间移动,您会看到不同的行为。 当然。这正是我选择这次的原因。 那你为什么不在问题中提及呢?为什么是 1918 年;今年的变化不会发生吗?你读过例如***.com/a/46185504/3001761? @jonrsharpe 我想很明显我没有意外选择 DST 开始的时间。(1918 年,因为我正在试验时区的旧变化。最初,我想看看 pytz知道相当古老的变化。见Wikipedia article。 【参考方案1】:

我不会接受以下内容,因为它只解释了如何正确地做。它没有解释为什么添加 timedelta 一开始就不能按预期方式工作。

如何解决

This answer建议采取以下方法:

from datetime import datetime, timezone, timedelta
import pytz

# Timezone-aware object to start with
t11 = datetime(1918, 4, 15, 0, 0, tzinfo=timezone.utc).astimezone(pytz.timezone('Europe/Berlin'))

# Extract timezone information
tzinfo = t11.tzinfo

# Convert to UTC, add timedelta, convert to local timezone
t13 = (t11.astimezone(pytz.timezone('utc')) + timedelta(hours=1)).astimezone(tzinfo)

另一种方法:

t14 = t11 + timedelta(hours=1)  # Invalid timezone!
t14 = t14.astimezone(pytz.utc).astimezone(t14.tzinfo)  # Fix the timezone

现在我有:

t11: 1918-04-15 01:00:00+01:00
t13: 1918-04-15 03:00:00+02:00  # one hour more and +1h because of DST

钟摆

pendulum 是另一种修复它的方法:

from pendulum import datetime
from datetime import timedelta
import pytz

t11 = datetime(1918, 4, 15, 0, 0).astimezone(pytz.timezone('Europe/Berlin'))
t12 = t11 + timedelta(hours=1)

t2 = datetime(1918, 4, 15, 1, 0).astimezone(pytz.timezone('Europe/Berlin'))

给予:

t11: 1918-04-15T01:00:00+01:00
t12: 1918-04-15T03:00:00+02:00
t2 : 1918-04-15T03:00:00+02:00

【讨论】:

以上是关于如果我将 UTC 时间加 1 小时并进行本地化,或者将本地时间加 1 小时,为啥会有所不同?的主要内容,如果未能解决你的问题,请参考以下文章

时间序列数据和UTC转换

java中utc时间怎么转换为本地时间

R将年-月-日-小时本地标准时间转换为UTC

查找页面上的所有时间(H:i)字符串并转换为UTC

如何从 tsql (sql 2005) 中的 utc 日期时间计算本地日期时间?

如何将角度 UTC 时间戳转换为本地时间戳? [复制]