我有一个档案。在Python中,我希望将其创建时间转换为ISO时间(ISO 8601)字符串,同时保留它是在东部时区(ET)创建的事实。

如何获取文件的ctime并将其转换为指示东部时区的ISO时间字符串(并在必要时考虑日光节约时间)?


当前回答

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时间格式的一部分。它不是唯一的。

Different libraries/different versions of the same library may use different time zone rules for the same date/timezone. If it is a future date then the rules might be unknown yet. In other words, the same UTC time may correspond to a different local time depending on what rules you use -- saving a time in ISO 8601 format preserves UTC time and the local time that corresponds to the current time zone rules in use on your platform. You might need to recalculate the local time on a different platform if it has different rules.

其他回答

我同意Jarek的观点,而且我还注意到ISO偏移分隔符字符是冒号,所以我认为最终的答案应该是:

isodate.datetime_isoformat(datetime.datetime.now()) + str.format('{0:+06.2f}', -float(time.timezone) / 3600).replace('.', ':')

标准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

ISO 8601时间表示

国际标准ISO 8601描述了日期和时间的字符串表示形式。这种格式的两个简单示例是

2010-12-16 17:22:15
20101216T172215

(两者都代表2010年12月16日),但该格式还允许亚秒级的分辨率时间和指定时区。这种格式当然不是python特有的,但它很适合以可移植的格式存储日期和时间。关于这种格式的详细信息可以在Markus Kuhn的条目中找到。

我建议使用这种格式在文件中存储时间。

在这种表示中获取当前时间的一种方法是使用Python标准库中的time模块中的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 datetime类文档 Egenix mxDateTime类

如果我错了请纠正我(我没有),但是与UTC的偏移量随着夏令时的变化而变化。所以你应该使用

tz = str.format('{0:+06.2f}', float(time.altzone) / 3600)

我也相信星座应该有所不同:

tz = str.format('{0:+06.2f}', -float(time.altzone) / 3600)

我可能是错的,但我不这么认为。

请让生活变得简单:

使用UTC时间 微秒 一行代码

f utcnow () {datetime。datetime。isoformat (): 3]) Z”

输出:

2022 - 02 - 25 - t02:08:40.684z