将数字偏移量转换为时区?
Posted
技术标签:
【中文标题】将数字偏移量转换为时区?【英文标题】:Convert numeric offset to a timezone? 【发布时间】:2021-06-29 19:02:42 【问题描述】:有一个网站以例如时间的形式提供时区信息。 -07:00
。有没有办法可以使用它来本地化 pytz
中的时间戳?
通常我会这样做:
EASTERN_TIMEZONE = pytz.timezone("US/Eastern")
date_in_pacific_time = EASTERN_TIMEZONE.localize(my_date)
其中my_date
是某个日期时间日期。但我不知道如何获取一个数字并从中获取时区,因此我可以将其应用于日期并从中获取时间戳。
这可能是一个 XY 问题,因为我想做的是获取一个日期字符串,如 "2021-04-02T18:30:04-07:00"
并将其转换为 Unix UTC 时间戳。
编辑:
像这样?
listing_date_string = "2021-04-02T18:30:04-07:00"
listing_date_string_datepart = listing_date_string[:19]
listing_date_string_timezone = int(listing_date_string[19:].replace(":00", ""))
d = datetime.datetime.strptime(listing_date_string_datepart, '%Y-%m-%dT%H:%M:%S')
d -= datetime.timedelta(hours=listing_date_string_timezone)
print(int(d.timestamp())) # outputs 1617427804
【问题讨论】:
ISO 格式:%Y-%m-%dT%H:%M:%S%z
,所以%z
是您所需要的。
@Simon 好像不匹配,ValueError: time data '2021-04-02T18:30:04-07:00' does not match format '%Y-%m-%dT%H:%M:%S%z'
你的python版本是多少?
【参考方案1】:
Python - 来自docs:
在 3.7 版中更改:当 %z 指令提供给 strptime() 方法,UTC 偏移量可以有一个冒号作为分隔符 在小时、分钟和秒之间。
反之亦然,这意味着对于较旧的 Python 版本,%z
不会解析带有冒号作为小时/分钟分隔符的 UTC 偏移量。你可以像这样解决问题
from datetime import datetime
# your input
s = "2021-04-02T18:30:04-07:00"
# parse separately, colon removed from UTC offset
tz = datetime.strptime(s[19:].replace(':', ''), '%z').tzinfo
dtobj = datetime.strptime(s[:19], "%Y-%m-%dT%H:%M:%S").replace(tzinfo=tz)
print(repr(dtobj))
datetime.datetime(2021, 4, 2, 18, 30, 4, tzinfo=datetime.timezone(datetime.timedelta(-1, 61200)))
如果您知道时区,则可以跳过解析 UTC 偏移量:
import pytz
tz = pytz.timezone('US/Pacific')
dtobj = tz.localize(datetime.strptime(s[:19], "%Y-%m-%dT%H:%M:%S"))
print(repr(dtobj))
datetime.datetime(2021, 4, 2, 18, 30, 4, tzinfo=<DstTzInfo 'US/Pacific' PDT-1 day, 17:00:00 DST>)
注意:pytz
is deprecated 随着 Python 3.9 的发布 - 您现在在标准库中拥有 zoneinfo。
在 Python 3.7+ 上,您可以只使用 fromisoformat;
dtobj = datetime.fromisoformat(s)
并从 UTC 偏移量更改为实际时区,例如
dtobj.astimezone(tz) # tz is a timezone object from pytz, dateutil, zoneinfo...
Out[9]: datetime.datetime(2021, 4, 2, 18, 30, 4, tzinfo=<DstTzInfo 'US/Pacific' PDT-1 day, 17:00:00 DST>)
【讨论】:
pytz 不再是解决 >2020 时区问题的正确方法,请参阅 bugs.launchpad.net/pytz/+bug/1884458 和 github.com/stub42/pytz/issues/48 中的讨论。zoneinfo
现在是标准(在一些没有系统范围的时区数据的系统上,如 Windows,以及 tzdata
包),至少建议人们改用 dateutil
。
@deadvoid:我知道一个人应该现在使用zoneinfo
...但是:我不认为这是问题的重点。 OP 明确要求使用 pytz。请记住,有很多遗留代码不能只用 zoneinfo 替换 pytz。对于 Python dateutil,因为它遵循与 zoneinfo 相同的语义。
好吧,有 backports.zoneinfo
用于较旧的 python 版本。是的,这确实意味着重构遗留代码,但考虑到人们在这些讨论链接中表达他们的关注的重要性,我认为这是值得的投资。此外,我想在大多数项目中这将是最小的变化并且有助于(至少一点)阻止更多人推广pytz
。【参考方案2】:
这对你有用吗?
import datetime
dt = datetime.datetime.strptime(
"2021-04-02T18:30:04-07:00",
"%Y-%m-%dT%H:%M:%S%z"
)
print(
dt.year,
dt.month,
dt.day,
dt.hour,
dt.minute,
dt.second,
dt.tzinfo,
)
2021 4 2 18 30 4 UTC-07:00
【讨论】:
不,ValueError: time data '2021-04-02T18:30:04-07:00' does not match format '%Y-%m-%dT%H:%M:%S%z'
【参考方案3】:
对于问题 X,一般来说是不可行的。 但是你有一些候选时区,比如
美国/太平洋 美国/凤凰城 美国/山区(与美国/丹佛相同)所以你可以尝试每一个,看看它是否匹配 -7 小时。
有些日子丹佛在 -7 小时, 在其他日子洛杉矶是-7 小时。 Phoenix一直在 -7 小时。
请注意,时区(例如 US/Mountain)与时区偏移量(例如 -7 小时)完全不同。
对于问题 Y,嗯,这很简单! 只需将第一部分视为UTC, 然后应用剩余的 -7 小时修正。
【讨论】:
愚蠢的问题,但 -7 是指“减去 7 以达到 UTC 时间”还是“我们从 UTC 时间返回 7 小时,所以加 7 到那里”? -7 表示位置在格林威治以西,而 +7 表示位置在格林威治以东。正午发生在伦敦~比凤凰城发生早七个小时。如果您的邮票是在凤凰城中午 12 点,加 7 以获得伦敦的 19:00(晚上 7 点)。 我更新了我的 OP,代码 sn-p 是正确的方法吗?以上是关于将数字偏移量转换为时区?的主要内容,如果未能解决你的问题,请参考以下文章
如何将“GMT + 5.5_(INDIA)”转换为时区“Asia / Kolkata”
multiboot2 标头在 ELF 文件中“为时已晚”(偏移量很大),即使它是第一部分