如何在Python中获取文件创建和修改日期/时间?


Answers:


620

以跨平台的方式获取某种修改日期很容易-只需调用,便会获得文件在以下位置时的Unix时间戳。os.path.getmtime(path)path最后修改时间。

另一方面,获取文件创建日期是不固定的,且取决于平台,即使在三个大型操作系统之间也有所不同:

综上所述,跨平台代码应如下所示:

import os
import platform

def creation_date(path_to_file):
    """
    Try to get the date that a file was created, falling back to when it was
    last modified if that isn't possible.
    See http://stackoverflow.com/a/39501288/1709587 for explanation.
    """
    if platform.system() == 'Windows':
        return os.path.getctime(path_to_file)
    else:
        stat = os.stat(path_to_file)
        try:
            return stat.st_birthtime
        except AttributeError:
            # We're probably on Linux. No easy way to get creation dates here,
            # so we'll settle for when its content was last modified.
            return stat.st_mtime

9
我已经竭尽全力将其组合在一起(并花了几个小时进行研究),并且我确信它至少比以前的答案更正确,但这是一个非常困难的话题,我d感谢人们可以提供的任何更正,澄清或其他投入。特别是,我想构建一种ext4在Linux下的驱动器上访问此数据的方法,并且我想了解当Linux读取Windows编写的文件(反之亦然)时发生的情况,因为它们使用的方式st_ctime不同。
Mark Amery

25
坦白说,文件创建时间通常是没有用的。当您打开现有文件进行模式写入时"w",它不会替换它,只会打开现有文件并将其截断。即使文件内容与创建时的内容完全无关,您仍然会被告知文件是在当前版本之前“创建”的。反之,在保存时使用原子替换的编辑器(原始文件被新的进行中的临时文件替换)将显示更新的日期,即使您只是删除了一个字符也是如此。使用修改时间,不要浪费创建时间。
ShadowRanger 2016年

3
多年后,我终于找到了用于创建文件的时间!我正在编写代码以检查某些目录中的文件命名约定,因此首先我要考虑在制定约定后首先命名的文件。更换的全部内容(修改时间)是无关紧要:如果它已经在那里了,然后它的祖父。
史蒂夫·杰索普

1
嗨,马克。我建议简化一下。在Linux上,返回stat.st_ctime更为相关,因为在许多情况下,最后一次元数据更改的时间可以是创建时间(至少比ctime实际创建时间短mtime)。因此,您只需将替换为即可stat = os.stat(path_to_file); try: return stat.st_birthtime; except AttributeError: return stat.st_ctime。你怎么看?干杯
olibre

4
@olibre “至少ctime比mtime更接近实际的创建时间” -不,不是;我已经看过好几次了,但这完全是错误的。除非你手动混乱与您的inode中的价值观,ctime应始终等于或更高版本mtime,因为mtime变化会导致一个ctime变化(因为mtime本身被认为是“元数据”)。请参阅stackoverflow.com/a/39521489/1709587,其中提供了一些示例代码来说明这一点。
Mark Amery

676

您有两种选择。首先,您可以使用os.path.getmtimeos.path.getctime功能:

import os.path, time
print("last modified: %s" % time.ctime(os.path.getmtime(file)))
print("created: %s" % time.ctime(os.path.getctime(file)))

您的另一个选择是使用os.stat

import os, time
(mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime) = os.stat(file)
print("last modified: %s" % time.ctime(mtime))

ctime()指创建时间在* nix系统,而是最后一次inode的数据变化。(感谢kojiro通过提供指向有趣的博客文章的链接使评论中的事实更加清楚)


169
万一有人错过@Glyph对这个问题的评论,ctime并不意味着在POSIX系统上的创建时间。我不知道过去三年里有多少人浏览了这篇文章,然后继续编写错误的代码。
2011年

16
请记住,第一个示例为您提供了一个字符串,而不是日期时间或数字。
gak

1
您链接到的@kojiro博客文章可以更明确地表明,在Unix上,文件ctime每次更新都会更新一次mtime(因为“ mtime是元数据”),因此,ctime通常总是等于或领先mtime。治疗ctime为“创造”的时间从而根本是没有意义的。-1!
Mark Amery

对于文件创建和最后修改,您的第一个选项将返回相同的结果! Last modified: Fri Jan 31 11:08:13 2020Created: Fri Jan 31 11:08:13 2020在Linux操作系统Ubuntu 16.04!
法里德Alijani

我发现该time.ctime(os.path.getmtime(file))返回2种类型的字符串,具体取决于文件是由系统还是由用户修改的。如果已被系统修改,则该字符串在月份和日期之间将有2个空格。我不知道为什么
Matteo Antolini

376

最好的功能是os.path.getmtime()。在内部,这只是使用os.stat(filename).st_mtime

datetime模块是最好的操作时间戳,因此您可以将修改日期作为这样的datetime对象获得:

import os
import datetime
def modification_date(filename):
    t = os.path.getmtime(filename)
    return datetime.datetime.fromtimestamp(t)

用法示例:

>>> d = modification_date('/var/log/syslog')
>>> print d
2009-10-06 10:50:01
>>> print repr(d)
datetime.datetime(2009, 10, 6, 10, 50, 1)

1
这个答案也有一点错误。getmtime是Unix上最接近的东西(无法获得创建日期),但绝对不是Windows上使用的最佳功能,因为Windows ctime是创建时间。
Mark Amery

3
@MarkAmery-这个答案被明确标记为即将修改。
ArtOfWarfare

47

os.stat https://docs.python.org/2/library/stat.html#module-stat

编辑:在较新的代码中,您可能应该使用os.path.getmtime()(感谢Christian Oudard),
但请注意,它返回的time_t浮点值只有小数秒(如果您的操作系统支持)


44
为此,创建了os.path.getmtime(),并且更加简单。
Christian Oudard

5
这里的“使用较新的代码”子句有点误导。os.path.getmtime()自从Python 1.5.2(见旧文档)问世以来,它就已经存在了,它是在我失去大部分乳齿之前以及大约在您编写此答案的原始版本之前十年发布的。
Mark Amery

39

有两种获取mod时间的方法,os.path.getmtime()或os.stat(),但是ctime不是可靠的跨平台(请参见下文)。

os.path.getmtime()

getmtimepath返回路径
的最后修改时间。返回值是一个数字,给出自纪元以来的秒数(请参见时间模块)。如果文件不存在或不可访问,请引发os.error。1.5.2版中的新功能。在版本2.3中进行了更改:如果os.stat_float_times()返回True,则结果为浮点数。

os.stat()

statpath
在给定路径上执行stat()系统调用。返回值是一个对象,其属性与stat结构的成员相对应,即:st_mode(保护位),st_ino(索引节点号),st_dev(设备),st_nlink(硬链接数),st_uid(所有者的用户ID) ),st_gid(所有者的组ID),st_size(文件大小,以字节为单位),st_atime(最新访问时间),st_mtime(最新内容修改时间),st_ctime(取决于平台;最新元数据更改的时间)在Unix上,或在Windows上创建的时间)

>>> import os
>>> statinfo = os.stat('somefile.txt')
>>> statinfo
(33188, 422511L, 769L, 1, 1032, 100, 926L, 1105022698,1105022732, 1105022732)
>>> statinfo.st_size
926L
>>> 

在上面的示例中,您将使用statinfo.st_mtime或statinfo.st_ctime分别获取mtime和ctime。


13

在Python 3.4及更高版本中,您可以使用面向对象的pathlib模块接口,该接口包括许多os模块的包装器。这是获取文件统计信息的示例。

>>> import pathlib
>>> fname = pathlib.Path('test.py')
>>> assert fname.exists(), f'No such file: {fname}'  # check that the file exists
>>> print(fname.stat())
os.stat_result(st_mode=33206, st_ino=5066549581564298, st_dev=573948050, st_nlink=1, st_uid=0, st_gid=0, st_size=413, st_atime=1523480272, st_mtime=1539787740, st_ctime=1523480272)

有关os.stat_result所含内容的更多信息,请参阅文档。对于您想要的修改时间fname.stat().st_mtime

>>> import datetime
>>> mtime = datetime.datetime.fromtimestamp(fname.stat().st_mtime)
>>> print(mtime)
datetime.datetime(2018, 10, 17, 10, 49, 0, 249980)

如果要在Windows上创建时间,或者在Unix上需要最新的元数据更改,则可以使用fname.stat().st_ctime

>>> ctime = datetime.datetime.fromtimestamp(fname.stat().st_ctime)
>>> print(ctime)
datetime.datetime(2018, 4, 11, 16, 57, 52, 151953)

本文提供了有关pathlib模块的更多有用信息和示例。


11

os.stat返回具有st_mtimest_ctime属性的命名元组。修改时间st_mtime在两个平台上都一样;不幸的是,在Windows上ctime表示“创建时间”,而在POSIX上表示“更改时间”。我不知道有什么方法可以在POSIX平台上获得创建时间。


这是有关标记元组的更多信息:stackoverflow.com/questions/2970608/…它们像元组一样工作,但请尝试dir(..)其中一个。例如dir(os.stat(os.listdir('.')[0]))
Evgeni Sergeev

9
import os, time, datetime

file = "somefile.txt"
print(file)

print("Modified")
print(os.stat(file)[-2])
print(os.stat(file).st_mtime)
print(os.path.getmtime(file))

print()

print("Created")
print(os.stat(file)[-1])
print(os.stat(file).st_ctime)
print(os.path.getctime(file))

print()

modified = os.path.getmtime(file)
print("Date modified: "+time.ctime(modified))
print("Date modified:",datetime.datetime.fromtimestamp(modified))
year,month,day,hour,minute,second=time.localtime(modified)[:-3]
print("Date modified: %02d/%02d/%d %02d:%02d:%02d"%(day,month,year,hour,minute,second))

print()

created = os.path.getctime(file)
print("Date created: "+time.ctime(created))
print("Date created:",datetime.datetime.fromtimestamp(created))
year,month,day,hour,minute,second=time.localtime(created)[:-3]
print("Date created: %02d/%02d/%d %02d:%02d:%02d"%(day,month,year,hour,minute,second))

版画

somefile.txt
Modified
1429613446
1429613446.0
1429613446.0

Created
1517491049
1517491049.28306
1517491049.28306

Date modified: Tue Apr 21 11:50:46 2015
Date modified: 2015-04-21 11:50:46
Date modified: 21/04/2015 11:50:46

Date created: Thu Feb  1 13:17:29 2018
Date created: 2018-02-01 13:17:29.283060
Date created: 01/02/2018 13:17:29

-1:与其他答案相同,这不会给您Windows上文件的创建时间(再次没有在答案中提到)。
ntninja

@ntninja你确定吗?我只使用Windows,这绝对可以。我在2015年初写了这个脚本。我发现它比这里的其他脚本更清晰,更直接,更完整,更能自我解释。(我碰巧决定在这里查找而不是我的旧脚本,以防万一有什么新东西。不,这是这样)
Puddle

哦,我的意思是说“…… 除非您在Windows上,否则这不会给您文件的创建时间”。抱歉! 事实仍然是,这个答案不是可移植的,并且没有提到这个事实。(Linux上的示例输出:pastebin.com/50r5vGBE
ntninja

@ntninja你要去告诉其他人吗?
水坑

已经在这里留下了一些其他评论,我将很快发布一个适用于(最新)Linux的答案。但是,实际上,您的帖子中唯一的错误是仅Windows的答案没有提及这一事实。在问题中,OP甚至专门要求Windows和Linux兼容的解决方案。因此,我认为将“详细信息”添加到顶部会很有帮助,这样人们就不会误以为ctime是针对多个平台的目标。
ntninja

2
>>> import os
>>> os.stat('feedparser.py').st_mtime
1136961142.0
>>> os.stat('feedparser.py').st_ctime
1222664012.233
>>> 

-1:如其他地方所述,除非您在Windows上,否则它不会为您提供文件的创建时间(答案根本没有提到!)。
ntninja

0

如果遵循符号链接并不重要,则也可以使用os.lstat内置函数。

>>> os.lstat("2048.py")
posix.stat_result(st_mode=33188, st_ino=4172202, st_dev=16777218L, st_nlink=1, st_uid=501, st_gid=20, st_size=2078, st_atime=1423378041, st_mtime=1423377552, st_ctime=1423377553)
>>> os.lstat("2048.py").st_atime
1423378041.0

这将给出最后一次读取的时间(至少在Unix上),这绝对不是要求的时间。
Mark Amery

0

值得一看的是该crtime库实现了对文件创建时间的跨平台访问。

from crtime import get_crtimes_in_dir

for fname, date in get_crtimes_in_dir(".", raise_on_error=True, as_epoch=False):
    print(fname, date)
    # file_a.py Mon Mar 18 20:51:18 CET 2019

1
我强烈建议您这样做:它debugfs在Linux上使用,从定义上来说,它是不稳定的,需要对所有内容进行顶级root访问,并且几乎每个方面都倾向于是您母亲经常警告您的事情之一。(但是,是的,如果您真的很绝望并且碰巧是没有安全启动的系统上的真正超级用户,它可能会起作用...)
ntninja

@ntninja我可能永远也不会在生产中使用它,但是它对于“家庭脚本”可能很有用。
德尔甘

-2

os.stat确实包括创建时间。对于os.stat()包含时间的元素,没有st_anything的定义。

所以试试这个:

os.stat('feedparser.py')[8]

将其与您在ls -lah中的文件上的创建日期进行比较

它们应该是相同的。


6
错误!os.stat('feedparser.py')[8]是指st_mtime,而不是创建时间。请参考文档:docs.python.org/library/os.html#os.stat
millerdev 2011年

4
请使用.st_ctime代替难看的数字[8]。
guettli

-3

通过运行系统的stat命令并解析输出,我能够在posix上获得创建时间。

commands.getoutput('stat FILENAME').split('\"')[7]

从终端(OS X)在python外部运行stat返回:

805306374 3382786932 -rwx------ 1 km staff 0 1098083 "Aug 29 12:02:05 2013" "Aug 29 12:02:05 2013" "Aug 29 12:02:20 2013" "Aug 27 12:35:28 2013" 61440 2150 0 testfile.txt

...其中第四个datetime是文件创建时间(而不是ctime更改时间,如其他注释所述)。


13
-1:从shell命令解析对人类有意义的输出是一个非常糟糕的主意。而且该命令甚至不是交叉兼容的。
MestreLion
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.