具体来说,考虑到我的服务器的时区(系统时间透视图)和时区输入,我如何计算系统时间,就像它在新的时区(无论夏令时等)一样?
import datetime
current_time = datetime.datetime.now() #system time
server_timezone = "US/Eastern"
new_timezone = "US/Pacific"
current_time_in_new_timezone = ???
答案 0 :(得分:19)
如果您知道要将其转换为原始时区和新时区,请先使用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)
当然,如果您想要的只是特定时区的当前时间,您可以将该时区直接传递到datetime.now()以获取时间戳。像这样:
datetime.datetime.now(new_timezone)
现在说了这些,我强烈建议将所有时间戳以UTC格式存储为系统标准,并避免整个DST问题。有关此内容,请参阅:http://lucumr.pocoo.org/2011/7/15/eppur-si-muove/
要知道一般来说处理时间计算有多困难:http://yourcalendricalfallacyis.com
答案 1 :(得分:3)
如何将日期时间/时间戳从一个时区转换为另一个时区?
有两个步骤:
从系统时间和时区创建一个有意识的日期时间对象,例如,获取给定时区的当前系统时间:
#!/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
注意:datetime.now(server_timezone)
works even during ambiguous times例如,在DST过渡期间,server_timezone.localize(datetime.now())
可能会失败(50%几率)。
如果您确定输入时间存在于服务器的时区并且它是唯一的,那么您可以通过is_dst=None
断言:
server_time = server_timezone.localize(naive_time, is_dst=None)
它引发了无效时间的例外
如果可以忽略高达一天错误(尽管通常由于DST导致的错误一小时),那么您可以删除is_dst
参数:
server_time = server_timezone.normalize(server_timezone.localize(naive_time))
调用 .normalize()
来调整不存在的时间(间隙中的本地时间,"向前弹跳"过渡)。如果时区规则没有改变;您的服务器不应该生成不存在的时间。请参阅"Can I just always set is_dst=True?"
将知晓的日期时间对象转换为目标时区tz
:
tz = pytz.timezone("US/Pacific")
server_time_in_new_timezone = server_time.astimezone(tz)
答案 2 :(得分:3)
使用 Python 3.9,标准库拥有您所需要的一切:zoneinfo。不再需要 pytz(已弃用;-> pytz deprecation 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))
print(current_time_in_new_timezone)
print(repr(current_time_in_new_timezone))
# 2021-05-02 02:02:38.976798-07:00
# datetime.datetime(2021, 5, 2, 2, 2, 38, 976798, tzinfo=zoneinfo.ZoneInfo(key='US/Pacific'))