python - 如何在保留时区的同时序列化时间对象?
问题描述
我正在尝试将time
-objects 序列化为 ISO8601 格式,同时使用 Python 3.8 保留它们的时区信息。
状态的文档time.isoformat
:
time.isoformat(timespec='auto')
返回一个以 ISO 8601 格式表示时间的字符串,其中之一是:
HH:MM:SS.ffffff
, 如果microsecond
不为 0HH:MM:SS
, 如果microsecond
是 0HH:MM:SS.ffffff+HH:MM[:SS[.ffffff]]
, 如果utcoffset()
不返回None
HH:MM:SS+HH:MM[:SS[.ffffff]]
, 如果microsecond
为 0utcoffset()
且不返回None
据我从该文档中了解到,我只需要生成一个time
-object,utcoffset()
它不会None
将时区信息作为 ISO8601 格式字符串的一部分获取。用作时区时效果很好datetime.timezone.utc
:
>>> from datetime import time, timezone
>>> t = time(1, 2, 3, tzinfo=timezone.utc)
>>> t
datetime.time(1, 2, 3, tzinfo=datetime.timezone.utc)
>>> t.utcoffset()
datetime.timedelta(0)
>>> t.isoformat()
'01:02:03+00:00'
但是,一旦我想使用 Python 标准库未提供的时区,这似乎不再适用。我试过了dateutil
,pytz
在这两种情况下都得到了相同的结果:
>>> from datetime import time
>>> from dateutil.tz import gettz
>>> t = time(1, 2, 3, tzinfo=gettz("US/Eastern"))
>>> t
datetime.time(1, 2, 3, tzinfo=tzfile('/usr/share/zoneinfo/US/Eastern'))
>>> t.utcoffset()
>>> t.isoformat()
'01:02:03'
>>> from datetime import time
>>> from pytz import timezone
>>> t = time(1, 2, 3, tzinfo=timezone("US/Eastern"))
>>> t
datetime.time(1, 2, 3, tzinfo=<DstTzInfo 'US/Eastern' LMT-1 day, 19:04:00 STD>)
>>> t.utcoffset()
>>> t.isoformat()
'01:02:03'
我也尝试过使用time.strftime()
,但这也不能解决我的问题:
>>> from datetime import time
>>> from dateutil.tz import gettz
>>> t = time(1, 2, 3, tzinfo=gettz("US/Eastern"))
>>> t.strftime("%H:%M:%S%z")
'01:02:03'
为什么会这样,我该如何解决这个问题?
解决方案
没有日期,时间不会给出明确的 UTC 偏移量。例如,在您的情况下,时区“美国/东部”在一年中部分具有夏令时,具有 UTC 偏移量EST
(UTC-5) 和EDT
(UTC-4)。Python 在那里很安静,不会在警告中告诉你。
如果添加日期,则strftime
有效:
import datetime as dt
from dateutil.tz import gettz
t_est = dt.datetime.combine(dt.date(2020,1,1), dt.time(1, 2, 3, tzinfo=gettz("US/Eastern")))
t_est.strftime("%H:%M:%S%z")
# '01:02:03-0500'
t_edt = dt.datetime.combine(dt.date(2020,6,6), dt.time(1, 2, 3, tzinfo=gettz("US/Eastern")))
t_edt.strftime("%H:%M:%S%z")
# '01:02:03-0400'
另一方面,如果您提供tzinfo
纯 UTC 偏移量,您的代码就可以工作。引用文档:
t = dt.time.fromisoformat('04:23:01+04:00')
# datetime.time(4, 23, 1, tzinfo=datetime.timezone(datetime.timedelta(seconds=14400)))
t.isoformat()
# '04:23:01+04:00'
例如,如果您知道所有时间对象都引用 EST,则可以使用相应的 UTC 偏移量:
t = dt.time(1, 2, 3, tzinfo=dt.timezone(dt.timedelta(seconds=3600*-5)))
t.isoformat()
# '01:02:03-05:00'
推荐阅读
- python - 使用单行从字符串python中过滤掉数字
- wordpress - 保持所有 WordPress 环境同步
- node.js - Electron --serve 因缺少 package.json 而失败
- javascript - 如何在 VScode 中显示导入的函数签名/jsdoc?
- java - Maven:“NoClassDefFoundError:com/jogamp/newt/event/KeyListener”
- neo4j - 使用密码投影的过程中不允许写入或令牌创建操作
- c# - 通过fast-mono-cgi运行asp.net,随机崩溃System.IO.DirectoryNotFoundException
- python - 谷歌云人才解决方案:如何使用 page_token
- r - R - 构建包时出错 - 无法安装到 srcdir
- c# - 如何在 C# 中解析 MTOM 肥皂响应