kfa*_*fan 18 python timezone datetime pytz timedelta
具体来说,考虑到我的服务器的时区(系统时间透视图)和时区输入,如何计算系统时间,就像它在新时区(无论夏令时等)一样?
import datetime
current_time = datetime.datetime.now() #system time
server_timezone = "US/Eastern"
new_timezone = "US/Pacific"
current_time_in_new_timezone = ???
Run Code Online (Sandbox Code Playgroud)
MrF*_*pes 30
在 Python 3.9 中,标准库拥有您所需的一切:zoneinfo。不再需要 pytz (已弃用;-> pytz 弃用 shim)。
前任:
from datetime import datetime
from zoneinfo import ZoneInfo
server_timezone = "US/Eastern"
new_timezone = "US/Pacific"
current_time = datetime.now(ZoneInfo(server_timezone))
# current_time_in_new_timezone = ???
current_time_in_new_timezone = current_time.astimezone(ZoneInfo(new_timezone))
Run Code Online (Sandbox Code Playgroud)
例如,这给了你
print(current_time.isoformat(timespec='seconds'))
# 2021-10-04T02:42:54-04:00
print(repr(current_time))
# datetime.datetime(2021, 10, 4, 2, 42, 54, 40600, tzinfo=zoneinfo.ZoneInfo(key='US/Eastern'))
print(current_time_in_new_timezone.isoformat(timespec='seconds'))
# 2021-10-03T23:42:54-07:00
print(repr(current_time_in_new_timezone))
# datetime.datetime(2021, 10, 3, 23, 42, 54, 40600, tzinfo=zoneinfo.ZoneInfo(key='US/Pacific'))
Run Code Online (Sandbox Code Playgroud)
kfa*_*fan 27
如果您知道要将其转换为原始时区和新时区,请先使用它pytz.localize
来处理任何本地化(例如夏令时等),然后使用pytz.timezone
创建时区对象,最后datetime.astimezone(timezone)
用于简单计算.例如:
import datetime
import pytz # new import
my_timestamp = datetime.datetime.now() # some timestamp
old_timezone = pytz.timezone("US/Eastern")
new_timezone = pytz.timezone("US/Pacific")
# returns datetime in the new timezone
my_timestamp_in_new_timezone = old_timezone.localize(my_timestamp).astimezone(new_timezone)
Run Code Online (Sandbox Code Playgroud)
当然,如果您想要的只是特定时区的当前时间,您可以将该时区直接传递到datetime.now()以获取时间戳.像这样:
datetime.datetime.now(new_timezone)
Run Code Online (Sandbox Code Playgroud)
尽管如此,我强烈建议将所有时间戳以UTC格式存储为系统标准,并避免整个DST问题.有关此内容,请参阅:http://lucumr.pocoo.org/2011/7/15/eppur-si-muove/
并且要知道处理时间计算有多么困难:http://yourcalendricalfallacyis.com
如何将日期时间/时间戳从一个时区转换为另一个时区?
有两个步骤:
从系统时间和时区创建一个感知日期时间对象,例如,获取给定时区中的当前系统时间:
#!/usr/bin/env python
from datetime import datetime
import pytz
server_timezone = pytz.timezone("US/Eastern")
server_time = datetime.now(server_timezone) # you could pass *tz* directly
Run Code Online (Sandbox Code Playgroud)
注意:datetime.now(server_timezone)
即使在不明确的时间也能工作,例如在 DST 转换期间,但server_timezone.localize(datetime.now())
可能会失败(50% 的几率)。
如果您确定您的输入时间存在于服务器的时区中并且它是唯一的,那么您可以通过is_dst=None
断言:
server_time = server_timezone.localize(naive_time, is_dst=None)
Run Code Online (Sandbox Code Playgroud)
它引发无效时间的异常。
如果可以忽略最多一天的错误(尽管通常由于 DST 导致的错误大约是一个小时),那么您可以删除is_dst
参数:
server_time = server_timezone.normalize(server_timezone.localize(naive_time))
Run Code Online (Sandbox Code Playgroud)
.normalize()
被调用来调整不存在的时间(间隙中的本地时间,在“spring forward”转换期间)。如果时区规则没有改变;您的服务器不应生成不存在的时间。请参阅“我可以始终设置 is_dst=True 吗?”
将感知日期时间对象转换为目标时区tz
:
tz = pytz.timezone("US/Pacific")
server_time_in_new_timezone = server_time.astimezone(tz)
Run Code Online (Sandbox Code Playgroud)