我有一个文件。 在Python中,我想花费它的创建时间,并将其转换为ISO时间(ISO 8601)字符串,同时保留它在东部时区(ET)中创建的事实。
如何获取文件的ctime并将其转换为指示东部时区的ISO时间字符串(并在必要时考虑夏令时)?
可能重复如何将ISO 8601日期时间字符串转换为Python日期时间对象?
@Nick-有用的链接,但不是重复 - 他要求转换另一种方式。
@ Joseph-我刚刚就RFC 3999问了这个问题 - 应该为此工作 - 在Python中生成RFC 3339时间戳
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()
带有TimeZone信息的UTC到ISO  8601(Python  3):
import datetime
datetime.datetime.utcnow().replace(tzinfo=datetime.timezone.utc).isoformat()
带有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()
对于Python 2,请参阅并使用pytz。
.isoformat()可以使用分隔符参数(如果您想要"T"以外的其他内容):.isoformat(' ')
@ThorSummoner很高兴知道!但请注意,更换分隔符将不再符合ISO-8601 ......这没有什么意义(此外,有更好的方法来打印日期,但这不是问题)。 RFC
允许空间作为ISO-8601标准的一部分。 <5233>
@raychi总是允许通过相互协议来改变标准(在许多情况下会破坏标准,但谁在乎它是否是相互协议,对吧?)。我的2c:只是不要,保持原样。
这个答案是错误的,因为datetime.datetime.now()。isoformat()返回一个本地ISO 8601字符串,而不将其标记为本地。你需要有一个表示当地时区的datetime.timezone来让isoformat做正确的事情。
看起来offset=utc_offset_sec应该替换为offset=datetime.timedelta(seconds=-utc_offset_sec)
可以通过使用:datetime.datetime.now(datetime.timezone(datetime.timedelta(seconds=time.localtime().tm_gmtoff))).isoformat()来改进"使用TimeZone信息(python 3)的本地到ISO-8601"部分。当您可以将tzinfo传递给now时,无需替换tzinfo,并且使用tm_gmtoff解决altzone问题。
如何在Python中获取ISO-8601的格式?因为我们需要strptime字符串。 %Y-%m-%dT%H:%M:%S%z返回-HHMM或+HHMM但不是-HH:MM。
UTC到ISO-8601,带有时区信息(使用pytz)datetime.datetime.now(tz=pytz.utc).isoformat()
但是我的其他javascript应用程序时间格式为2019-02-23T04:01:55.360Z,Z为零小时偏移,是不是有这种格式的选项?
这是我用来转换为XSD日期时间格式的内容:
from datetime import datetime
datetime.now().replace(microsecond=0).isoformat()
# You get your ISO string
在查找XSD日期时间格式(xs:dateTime)时,我遇到了这个问题。我需要从isoformat中删除微秒。
什么是"XSD"(在此背景下)?
我相信他的意思是来自XSD / XML样式表的xs:date。
这意味着xs:dateTime
我在文档中找到了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时间表示
国际标准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类
在什么感觉它"更强大"?
日期:2018-05-25
以UTC格式组合的日期和时间:2018-05-25T12:16:14+00:00
以UTC格式组合的日期和时间:2018-05-25T12:16:14Z
以UTC格式组合的日期和时间:20180525T121614Z
如何以UTC格式创建此组合日期和时间:2018-05-25T12:16:14Z @Ioxaxs
ISO 8601时间格式不存储时区名称,仅保留相应的UTC偏移。
要将文件ctime转换为ISO&nbsp; 8601时间字符串,同时在Python中保留UTC偏移量&nbsp; 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可以访问系统上的历史时区数据库或时间区域在给定日期具有相同的规则。
如果您需要便携式解决方案;使用提供对tz数据库的访问的pytz模块:
>>> 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&nbsp; 8601时间格式的一部分。它不是唯一的。
同一库的不同库/不同版本可以对同一日期/时区使用不同的时区规则。如果是未来日期,则规则可能尚未知晓。换句话说,相同的UTC时间可能对应于不同的本地时间,具体取决于您使用的规则 - 以ISO&nbsp; 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'
时区是否适用于夏令时?无论夏令时如何,似乎tz都是一样的。
它将是当前有效的任何偏移量。如果DST处于活动状态,则它将与DST不同时具有不同的偏移量。
ISO&nbsp; 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'
有没有办法将毫秒的数字限制为3?即我的其他JavaScript应用程序将生成2019-02-23T04:02:04.051Z与new Date().toISOString()
如果我错了(我不是),请纠正我,但UTC的偏移会随着夏令时而变化。所以你应该使用
tz = str.format('{0:+06.2f}', float(time.altzone) / 3600)
我也相信标志应该是不同的:
tz = str.format('{0:+06.2f}', -float(time.altzone) / 3600)
我错了,但我不这么认为。
我同意Jarek,而且我还注意到ISO偏移分隔符是一个冒号,所以我认为最终的答案应该是:
isodate.datetime_isoformat(datetime.datetime.now()) + str.format('{0:+06.2f}', -float(time.timezone) / 3600).replace('.', ':')
我开发了这个功能:
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