我有一个档案。在Python中,我想保留其创建时间,并将其转换为ISO时间(ISO 8601)字符串, 同时保留它是在东部时区(ET)创建的事实。
如何获取文件的ctime并将其转换为表示东部时区的ISO时间字符串(并在必要时考虑夏令时)?
我有一个档案。在Python中,我想保留其创建时间,并将其转换为ISO时间(ISO 8601)字符串, 同时保留它是在东部时区(ET)创建的事实。
如何获取文件的ctime并将其转换为表示东部时区的ISO时间字符串(并在必要时考虑夏令时)?
Answers:
ISO 8601的本地:
import datetime
datetime.datetime.now().isoformat()
>>> 2020-03-20T14:28:23.382748
UTC符合ISO 8601:
import datetime
datetime.datetime.utcnow().isoformat()
>>> 2020-03-20T01:30:08.180856
ISO 8601本地,无微秒:
import datetime
datetime.datetime.now().replace(microsecond=0).isoformat()
>>> 2020-03-20T14:30:43
具有TimeZone信息的UTC到ISO 8601(Python 3):
import datetime
datetime.datetime.utcnow().replace(tzinfo=datetime.timezone.utc).isoformat()
>>> 2020-03-20T01:31:12.467113+00:00
UTC到ISO 8601,具有本地时区信息,无微秒(Python 3):
import datetime
datetime.datetime.now().astimezone().replace(microsecond=0).isoformat()
>>> 2020-03-20T14:31:43+13:00
具有TimeZone信息的ISO 8601本地(Python 3):
import datetime
datetime.datetime.now().astimezone().isoformat()
>>> 2020-03-20T14:32:16.458361+13:00
注意astimezone()
在utc时间使用时有一个错误。这给出了错误的结果:
datetime.datetime.utcnow().astimezone().isoformat() #Incorrect result
对于Python 2,请参阅并使用pytz。
.isoformat()
可以采用分隔符参数,(如果您想要除“ T”以外的其他值):.isoformat(' ')
It is permitted to omit the 'T' character by mutual agreement.
这是我用来转换为XSD日期时间格式的方法:
from datetime import datetime
datetime.now().replace(microsecond=0).isoformat()
# You get your ISO string
我在寻找XSD日期时间格式(xs:dateTime
)时遇到了这个问题。我需要从中删除微秒isoformat
。
xs:date
来自XSD / XML样式表。
xs:dateTime
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)
参考文献
2018-05-25
2018-05-25T12:16:14+00:00
2018-05-25T12:16:14Z
20180525T121614Z
我在文档中找到了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'
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'
编辑:
阅读更多内容后,建议您不要使用标点符号。RFC3339建议使用这种样式,因为如果每个人都使用标点符号,则不会有多个ISO 8601字符串按标点符号分组的风险。因此,符合要求的字符串的一个衬里是:
>>> datetime.datetime.now().strftime("%Y-%m-%dT%H:%M%SZ")
'2018-09-05T14:09:03Z'
2019-02-23T04:02:04.051Z
与new Date().toISOString()
在ISO 8601时的格式不存储时区的名称,只有相应的UTC偏移被保留。
要将文件ctime转换为ISO 8601时间字符串,同时在Python中保留UTC偏移量3:
>>> 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时间,并且本地时间与平台上使用的当前时区规则相对应。如果规则不同,则可能需要在其他平台上重新计算本地时间。
您需要使用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'
如果我错了(不是),请纠正我,但是与UTC的偏差会随着夏时制而变化。所以你应该使用
tz = str.format('{0:+06.2f}', float(time.altzone) / 3600)
我还认为该标志应有所不同:
tz = str.format('{0:+06.2f}', -float(time.altzone) / 3600)
我可能是错的,但我不这么认为。
在estani的出色回答中添加了一个小的变化
具有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
我开发了此功能:
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
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