Python中的ISO时间(ISO 8601)

时间:2010-01-27 22:22:37

标签: python datetime iso8601

我有一个档案。在Python中,我想花费它的创建时间,并将其转换为ISO time (ISO 8601) string ,同时保留它是在Eastern Time Zone(ET)中创建的。

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

14 个答案:

答案 0 :(得分:325)

ISO 8601的本地化:

import datetime
datetime.datetime.now().isoformat()

UTC到ISO 8601:

import datetime
datetime.datetime.utcnow().isoformat()

没有微秒的ISO 8601本地化:

import datetime
datetime.datetime.now().replace(microsecond=0).isoformat()

UTC到ISO 8601,带有TimeZone信息(Python 3):

import datetime
datetime.datetime.utcnow().replace(tzinfo=datetime.timezone.utc).isoformat()

使用TimeZone信息(Python 3)对ISO 8601进行本地化:

import datetime, time

# Calculate the offset taking into account daylight saving 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(tzinfo=datetime.timezone(offset=utc_offset)).isoformat()

对于Python 2,请参阅并使用pytz

答案 1 :(得分:48)

我在the documentation找到了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'

答案 2 :(得分:46)

ISO 8601时间表示

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

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

(两者均代表2010年12月16日),但格式也允许亚秒级分辨率时间并指定时区。这种格式当然不是特定于Python的,但它适合以便携式格式存储日期和时间。有关此格式的详细信息,请参阅Markus Kuhn entry

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

在此表示中获取当前时间的一种方法是使用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)

<强>参考

答案 3 :(得分:44)

以下是我用来转换为XSD日期时间格式的内容:

from datetime import datetime
datetime.now().replace(microsecond=0).isoformat()
# You get your ISO string

在查找XSD日期时间格式(xs:dateTime)时,我遇到了这个问题。我需要从isoformat删除微秒。

答案 4 :(得分:15)

ISO 8601 time format不存储时区名称,仅保留相应的UTC偏移量。

要将文件ctime转换为ISO 8601时间字符串,同时在Python 3中保留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'

代码假定您的本地时区为Eastern Time Zone(ET),并且您的系统为给定的POSIX时间戳(ts)提供了正确的UTC偏移量,即Python可以访问历史时区系统或时区上的数据库在给定日期具有相同的规则。

如果您需要便携式解决方案; use the pytz module提供the tz database的访问权限:

>>> 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时间和与当前时间对应的本地时间您平台上使用的区域规则。如果它有不同的规则,您可能需要在不同的平台上重新计算本地时间。

答案 5 :(得分:13)

您需要使用os.stat来获取文件创建时间以及time.strftimetime.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'

答案 6 :(得分:8)

ISO 8601允许紧凑的表示形式,除了T之外没有任何分隔符,所以我喜欢使用这种单线来获得快速的时间戳字符串:

>>> datetime.datetime.utcnow().strftime("%Y%m%dT%H%M%S.%fZ")
'20180905T140903.591680Z'

如果不需要微秒,只需忽略.%f部分:

>>> datetime.datetime.utcnow().strftime("%Y%m%dT%H%M%SZ")
'20180905T140903Z'

对于本地时间:

>>> datetime.datetime.now().strftime("%Y%m%dT%H%M%S")
'20180905T140903'

答案 7 :(得分:4)

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

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

我也相信标志应该是不同的:

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

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

答案 8 :(得分:4)

对于那些只寻求日期解决方案的人,它是:

import datetime

datetime.date.today().isoformat()

答案 9 :(得分:2)

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

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

答案 10 :(得分:2)

以毫秒为单位的标准 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 :(得分:1)

为estani的excellent answer

添加了一个小的变体

具有TimeZone且微秒信息(Python 3)的ISO 8601本地版本:

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'

测试此输出可以被Javascript Date和C#DateTime / DateTimeOffset解析

答案 12 :(得分:0)

我已经开发了这个功能:

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

答案 13 :(得分:-6)

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')+\
                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