Python 中的 ISO 时间 (ISO 8601)
- 2025-02-18 09:23:00
- admin 原创
- 42
问题描述:
我有一个文件。在 Python 中,我想获取其创建时间,并将其转换为ISO 时间 (ISO 8601) 字符串,同时保留它是在 东部时区(ET)创建的事实。
我如何获取文件的 ctime 并将其转换为指示东部时区的 ISO 时间字符串(如果需要,还要考虑夏令时)?
解决方案 1:
本地至 ISO 8601:
import datetime
datetime.datetime.now().isoformat()
>>> '2024-08-01T14:38:32.499588'
UTC 至 ISO 8601:
import datetime
datetime.datetime.now(datetime.timezone.utc).isoformat()
>>> '2024-08-01T04:38:47.731215+00:00'
本地符合 ISO 8601 标准(无微秒):
import datetime
datetime.datetime.now().replace(microsecond=0).isoformat()
>>> '2024-08-01T14:38:57'
带有时区信息的 UTC 到 ISO 8601(Python 3):
import datetime
datetime.datetime.now(datetime.timezone.utc).isoformat()
>>> '2024-08-01T04:39:06.274874+00:00'
本地 ISO 8601,带有时区信息(Python 3):
import datetime
datetime.datetime.now().astimezone().isoformat()
>>> '2024-08-01T14:39:16.698776+10:00'
本地到 ISO 8601,带有本地时区信息(无微秒)(Python 3):
import datetime
datetime.datetime.now().astimezone().replace(microsecond=0).isoformat()
>>> '2024-08-01T14:39:28+10:00'
astimezone()
注意使用on时有一个错误utcnow()
。这会产生不正确的结果:
datetime.datetime.utcnow().astimezone().isoformat() #Incorrect result, do not use.
.utcnow()
已被弃用,请改用.now(datetime.timezome.utc)
。
对于 Python 2,请参阅并使用pytz。
解决方案 2:
ISO 8601 允许紧凑表示,除了 之外没有分隔符T
,所以我喜欢使用这一行来快速获取时间戳字符串:
>>> datetime.datetime.now(datetime.UTC).strftime("%Y%m%dT%H%M%S.%fZ")
'20180905T140903.591680Z'
如果您不需要微秒,则只需省略该.%f
部分:
>>> datetime.datetime.now(datetime.UTC).strftime("%Y%m%dT%H%M%SZ")
'20180905T140903Z'
当地时间:
>>> datetime.datetime.now(datetime.timezone(datetime.timedelta(hours=-5))).strftime("%Y-%m-%dT%H:%M:%S%:z")
'2018-09-05T14:09:03-05:00'
一般来说,我建议你保留标点符号。RFC 3339建议使用这种风格,因为如果每个人都使用标点符号,就不会出现多个 ISO 8601 字符串按标点符号分组排序的风险。因此,符合要求的字符串的一行代码将是:
>>> datetime.datetime.now(datetime.UTC).strftime("%Y-%m-%dT%H:%M:%SZ")
'2018-09-05T14:09:03Z'
解决方案 3:
以下是我用来转换为 XSD 日期时间格式的内容:
from datetime import datetime
datetime.now().replace(microsecond=0).isoformat()
# You get your ISO string
我在寻找 XSD 日期时间格式 ( xs:dateTime
) 时遇到了这个问题。我需要从中删除微秒isoformat
。
解决方案 4:
ISO 8601 时间表示
国际标准 ISO 8601 描述了日期和时间的字符串表示。此格式的两个简单示例是
2010-12-16 17:22:15
20101216T172215
(均代表 2010 年 12 月 16 日),但该格式还允许亚秒级分辨率的时间并指定时区。这种格式当然不是 Python 特有的,但它非常适合以可移植格式存储日期和时间。有关此格式的详细信息,请参阅Markus Kuhn 条目。
我建议使用这种格式在文件中存储时间。
以这种表示形式获取当前时间的一种方法是使用 Python 标准库中时间模块的 strftime:
>>> from time import strftime
>>> strftime("%Y-%m-%d %H:%M:%S")
'2010-03-03 21:16:45'
您可以使用 datetime 类的 strptime 构造函数:
>>> from datetime import datetime
>>> datetime.strptime("2010-06-04 21:08:12", "%Y-%m-%d %H:%M:%S")
datetime.datetime(2010, 6, 4, 21, 8, 12)
最强大的是 Egenix mxDateTime 模块:
>>> from mx.DateTime.ISO import ParseDateTimeUTC
>>> from datetime import datetime
>>> x = ParseDateTimeUTC("2010-06-04 21:08:12")
>>> datetime.fromtimestamp(x)
datetime.datetime(2010, 3, 6, 21, 8, 12)
参考
Python 时间模块文档
Python 日期时间类文档
Egenix mxDateTime 类
解决方案 5:
我在文档中找到了 datetime.isoformat 。它似乎可以满足您的要求:
datetime.isoformat([sep])
Return a string representing the date and time in ISO 8601 format, YYYY-MM-DDTHH:MM:SS.mmmmmm or, if microsecond is 0, YYYY-MM-DDTHH:MM:SS
If utcoffset() does not return None, a 6-character string is appended, giving the UTC offset in (signed) hours and minutes: YYYY-MM-DDTHH:MM:SS.mmmmmm+HH:MM or, if microsecond is 0 YYYY-MM-DDTHH:MM:SS+HH:MM
The optional argument sep (default 'T') is a one-character separator, placed between the date and time portions of the result. For example,
>>>
>>> from datetime import tzinfo, timedelta, datetime
>>> class TZ(tzinfo):
... def utcoffset(self, dt): return timedelta(minutes=-399)
...
>>> datetime(2002, 12, 25, tzinfo=TZ()).isoformat(' ')
'2002-12-25 00:00:00-06:39'
解决方案 6:
对于那些正在寻找仅限日期的解决方案的人来说,它是:
import datetime
datetime.date.today().isoformat()
解决方案 7:
ISO 8601 时间格式不存储时区名称,只保留相应的 UTC 偏移量。
要在 Python 3 中将文件 ctime 转换为 ISO 8601 时间字符串,同时保留 UTC 偏移量:
>>> import os
>>> from datetime import datetime, timezone
>>> ts = os.path.getctime(some_file)
>>> dt = datetime.fromtimestamp(ts, timezone.utc)
>>> dt.astimezone().isoformat()
'2015-11-27T00:29:06.839600-05:00'
代码假定您的本地时区是 东部时区(ET),并且您的系统为给定的 POSIX 时间戳(ts
)提供了正确的 UTC 偏移量,即 Python 可以访问您系统上的历史时区数据库或时区在给定日期具有相同的规则。
如果您需要便携式解决方案;请使用提供对pytz
tz 数据库进行访问的模块:
>>> import os
>>> from datetime import datetime
>>> import pytz # pip install pytz
>>> ts = os.path.getctime(some_file)
>>> dt = datetime.fromtimestamp(ts, pytz.timezone('America/New_York'))
>>> dt.isoformat()
'2015-11-27T00:29:06.839600-05:00'
在这种情况下,结果是相同的。
如果需要时区名称/缩写/区域id,请单独存储。
>>> dt.astimezone().strftime('%Y-%m-%d %H:%M:%S%z (%Z)')
'2015-11-27 00:29:06-0500 (EST)'
注意:不,:
UTC 偏移量和EST
时区缩写不是 ISO 8601 时间格式的一部分。它不是唯一的。
不同的库/同一库的不同版本可能对同一日期/时区使用不同的时区规则。如果是未来日期,则规则可能尚不清楚。换句话说,相同的 UTC 时间可能对应于不同的本地时间,具体取决于您使用的规则 - 以 ISO 8601 格式保存时间会保留 UTC 时间和与您平台上当前使用的时区规则相对应的本地时间。如果不同平台有不同的规则,您可能需要重新计算本地时间。
解决方案 8:
请让生活变得简单:
使用 UTC 时间
微秒
一行代码
f"{datetime.datetime.utcnow().isoformat()[:-3]}Z"
输出:
2022-02-25T02:08:40.684Z
解决方案 9:
您需要使用来获取文件创建时间以及和os.stat
的组合来进行格式化:time.strftime
`time.timezone`
>>> import time
>>> import os
>>> t = os.stat('C:/Path/To/File.txt').st_ctime
>>> t = time.localtime(t)
>>> formatted = time.strftime('%Y-%m-%d %H:%M:%S', t)
>>> tz = str.format('{0:+06.2f}', float(time.timezone) / 3600)
>>> final = formatted + tz
>>>
>>> final
'2008-11-24 14:46:08-02.00'
解决方案 10:
标准 RFC-3339(以毫秒为单位)
我需要这种格式的时间用于 LoRa 应用程序,所以我想到了这个,希望它有所帮助:
from datetime import datetime
from time import strftime
# Get the current time in the format: 2021-03-20T16:51:23.644+01:00
def rfc3339_time_ms():
datetime_now = datetime.utcnow()
# Remove the microseconds
datetime_now_ms = datetime_now.strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3]
# Add the timezone as "+/-HHMM", and the colon in "+/-HH:MM"
datetime_now_ms_tz = datetime_now_ms + strftime("%z")
rfc3339_ms_now = datetime_now_ms_tz[:-2] + ":" + datetime_now_ms_tz[-2:]
# print(f"Current time in ms in RFC-3339 format: {rfc3339_ms_now}")
return rfc3339_ms_now
解决方案 11:
如果我错了,请纠正我(我没有错),但与 UTC 的偏移量会随着夏令时而变化。因此您应该使用
tz = str.format('{0:+06.2f}', float(time.altzone) / 3600)
我也认为标志应该有所不同:
tz = str.format('{0:+06.2f}', -float(time.altzone) / 3600)
我可能错了,但我不这么认为。
解决方案 12:
对 estani 的优秀答案添加一个小的变化
本地为 ISO 8601,具有时区并且没有微秒信息(Python 3):
import datetime, time
utc_offset_sec = time.altzone if time.localtime().tm_isdst else time.timezone
utc_offset = datetime.timedelta(seconds=-utc_offset_sec)
datetime.datetime.now().replace(microsecond=0, tzinfo=datetime.timezone(offset=utc_offset)).isoformat()
示例输出:
'2019-11-06T12:12:06-08:00'
Date
测试了此输出是否可以被 Javascript和 C#解析DateTime
/DateTimeOffset
解决方案 13:
我同意 Jarek 的观点,而且我还注意到 ISO 偏移分隔符是冒号,因此我认为最终答案应该是:
isodate.datetime_isoformat(datetime.datetime.now()) + str.format('{0:+06.2f}', -float(time.timezone) / 3600).replace('.', ':')
解决方案 14:
我已经开发了这个功能:
def iso_8601_format(dt):
"""YYYY-MM-DDThh:mm:ssTZD (1997-07-16T19:20:30-03:00)"""
if dt is None:
return ""
fmt_datetime = dt.strftime('%Y-%m-%dT%H:%M:%S')
tz = dt.utcoffset()
if tz is None:
fmt_timezone = "+00:00"
else:
fmt_timezone = str.format('{0:+06.2f}', float(tz.total_seconds() / 3600))
return fmt_datetime + fmt_timezone
解决方案 15:
import datetime, time
def convert_enddate_to_seconds(self, ts):
"""Takes ISO 8601 format(string) and converts into epoch time."""
dt = datetime.datetime.strptime(ts[:-7],'%Y-%m-%dT%H:%M:%S.%f')+\n datetime.timedelta(hours=int(ts[-5:-3]),
minutes=int(ts[-2:]))*int(ts[-6:-5]+'1')
seconds = time.mktime(dt.timetuple()) + dt.microsecond/1000000.0
return seconds
>>> import datetime, time
>>> ts = '2012-09-30T15:31:50.262-08:00'
>>> dt = datetime.datetime.strptime(ts[:-7],'%Y-%m-%dT%H:%M:%S.%f')+ datetime.timedelta(hours=int(ts[-5:-3]), minutes=int(ts[-2:]))*int(ts[-6:-5]+'1')
>>> seconds = time.mktime(dt.timetuple()) + dt.microsecond/1000000.0
>>> seconds
1348990310.26
- 2025年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 项目管理必备:盘点2024年13款好用的项目管理软件
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)