Python中的ISO时间(ISO 8601)

Jos*_*ian 267 python datetime iso8601

我有一个文件.在Python中,我想花费它的创建时间,并将其转换为ISO时间(ISO 8601)字符串, 同时保留它在东部时区(ET)中创建的事实.

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

est*_*ani 415

ISO 8601本地:

import datetime
datetime.datetime.now().isoformat()
Run Code Online (Sandbox Code Playgroud)

UTC至ISO 8601:

import datetime
datetime.datetime.utcnow().isoformat()
Run Code Online (Sandbox Code Playgroud)

本地到ISO 8601没有微秒:

import datetime
datetime.datetime.now().replace(microsecond=0).isoformat()
Run Code Online (Sandbox Code Playgroud)

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

import datetime
datetime.datetime.utcnow().replace(tzinfo=datetime.timezone.utc).isoformat()
Run Code Online (Sandbox Code Playgroud)

带有TimeZone信息的本地ISO 8601(Python 3):

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()
Run Code Online (Sandbox Code Playgroud)

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

  • `.isoformat()`可以带一个separator参数,(如果你想要'T'以外的东西):`.isoformat('')` (10认同)
  • 这个答案是错误的,因为datetime.datetime.now().isoformat()返回一个本地ISO 8601字符串,而不将其标记为本地.你需要有一个datetime.timezone代表当地时区来让isoformat做正确的事情. (10认同)
  • @ThorSummoner很高兴知道!但请注意,更换分隔符将不再符合ISO-8601 ......这没有什么意义(此外,有更好的方法来打印日期,但这不是问题).[RFC(https://tools.ietf.org/html/rfc3339#section-5.6) (5认同)
  • 允许空间作为ISO-8601标准的一部分.`允许通过双方协议省略'T'字符 (4认同)
  • @raychi总是允许通过共同协议来改变标准(在许多情况下会破坏标准,但谁在乎它是否是共同协议,对吧?).我的2c:只是不要,保持原样. (4认同)
  • "Local to ISO-8601 with TimeZone info (python 3)" 部分可以通过使用来改进:`datetime.datetime.now(datetime.timezone(datetime.timedelta(seconds=time.localtime().tm_gmtoff)))。等格式()`。把`tzinfo`传给`now`就不用替换了,`tm_gmtoff`解决了`altzone`问题。 (2认同)
  • 但是我的另一个 javascript 应用程序时间的格式是`2019-02-23T04:01:55.360Z`,`Z` 表示零时差,没有这种格式的选项吗? (2认同)
  • 带有时区信息的 UTC 到 ISO-8601(Python 3,不带 pytz):`datetime.datetime.now(tz=datetime.timezone.utc).isoformat()` (2认同)
  • 省略“T”不会改变标准,因为它是 ISO 8601 标准的一部分。 (2认同)

rad*_*tek 61

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

from datetime import datetime
datetime.now().replace(microsecond=0).isoformat()
# You get your ISO string
Run Code Online (Sandbox Code Playgroud)

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

  • 什么是*“ XSD” *(在此情况下)? (4认同)
  • 我相信他的意思是 XSD/XML 样式表中的“xs:date”。 (2认同)

Voi*_*uca 51

ISO 8601时间表示

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

2010-12-16 17:22:15
20101216T172215
Run Code Online (Sandbox Code Playgroud)

(两者均代表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'
Run Code Online (Sandbox Code Playgroud)

您可以使用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)
Run Code Online (Sandbox Code Playgroud)

最强大的是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)
Run Code Online (Sandbox Code Playgroud)

参考

  • 在什么感觉它"更强大"? (2认同)
  • 以UTC结合的日期和时间:`2018-05-25T12:16:14Z` (2认同)

小智 49

我在文档中找到了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'
Run Code Online (Sandbox Code Playgroud)

  • 你能解释一下你是如何得到正确的时间的吗? (4认同)

Joh*_*n_J 19

请让生活变得简单:

  1. 使用UTC时间
  2. 微秒
  3. 一行代码

f"{datetime.datetime.utcnow().isoformat()[:-3]}Z"

输出:

2022-02-25T02:08:40.684Z


jfs*_*jfs 18

ISO 8601时的格式不存储时区的名称,只有相应的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'
Run Code Online (Sandbox Code Playgroud)

该代码假定您的本地时区是 东部时区(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'
Run Code Online (Sandbox Code Playgroud)

在这种情况下结果是相同的.

如果您需要时区名称/缩写/区域ID,请单独存储.

>>> dt.astimezone().strftime('%Y-%m-%d %H:%M:%S%z (%Z)')
'2015-11-27 00:29:06-0500 (EST)'
Run Code Online (Sandbox Code Playgroud)

注意:不,:UTC偏移和EST时区缩写不是ISO 8601时间格式的一部分.它不是唯一的.

同一库的不同库/不同版本可以对同一日期/时区使用不同的时区规则.如果是未来日期,则规则可能尚未知晓.换句话说,相同的UTC时间可能对应于不同的本地时间,具体取决于您使用的规则 - 以ISO 8601格式保存时间可保留UTC时间以及与您平台上使用的当前时区规则相对应的本地时间.如果具有不同的规则,您可能需要在不同的平台上重新计算本地时间.


Jim*_*ker 15

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

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

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

>>> datetime.datetime.utcnow().strftime("%Y%m%dT%H%M%SZ")
'20180905T140903Z'
Run Code Online (Sandbox Code Playgroud)

对于当地时间:

>>> datetime.datetime.now().strftime("%Y%m%dT%H%M%S")
'20180905T140903'
Run Code Online (Sandbox Code Playgroud)

  • @Dr_Zaszuś 这是不对的。%z 为您的本地时间生成时区偏移量,这不是我建议的时间戳,特别是在您查看多个系统时。文字 Z 是 ISO 8601 UTC 的简写。 (3认同)
  • 有没有办法将毫秒数限制为3?即我的其他JavaScript应用程序将使用`new Date()。toISOString()`产生`2019-02-23T04:02:04.051Z` (2认同)
  • 警告:末尾的“Z”不正确。输出包含 'Z' 符号的时区的正确方法是 '%z' 或 '%Z',这使得它 'datetime.datetime.now().strftime("%Y-%m-%dT%H :%M:%S%z")'。我花了 2 个小时试图找到我的代码中的错误...... (2认同)

Ale*_*huk 15

对于那些正在寻找仅限日期的解决方案的人来说,它是:

import datetime

datetime.date.today().isoformat()
Run Code Online (Sandbox Code Playgroud)


Max*_*keh 14

你需要使用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'
Run Code Online (Sandbox Code Playgroud)

  • 它将是当前有效的任何偏移量.如果DST处于活动状态,则它将与DST不同时具有不同的偏移量. (2认同)

小智 6

标准 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
Run Code Online (Sandbox Code Playgroud)