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

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


当前回答

在estani的精彩回答中加入一个小变化

本地到ISO 8601,带时区,没有微秒信息(Python 3):

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解析

其他回答

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

import datetime

datetime.date.today().isoformat()

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.

你需要使用操作系统。Stat来获取文件创建时间和时间的组合。时间和时间。用于格式化的时区:

>>> 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)

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

本地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

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

本地到ISO 8601,带时区信息(Python 3):

import datetime
datetime.datetime.now().astimezone().isoformat()
>>> 2020-03-20T14:32:16.458361+13:00

注意,在utc时间上使用astimezone()时有一个错误。这给出了一个错误的结果:

datetime.datetime.utcnow().astimezone().isoformat() #Incorrect result

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