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

How do I get file creation and modification date/times?

提问人:Mark Biek 提问时间:10/26/2008 最后编辑:Mateen UlhaqMark Biek 更新时间:3/3/2023 访问量:1219342

问:

获取文件创建和修改日期/时间的最佳跨平台方法是什么,适用于 Linux 和 Windows?

python 文件

评论

71赞 Glyph 7/20/2010
您无法以跨平台方式获取文件创建时间。查看 docs.python.org/library/os.path.html#os.path.getctime
6赞 questionto42 12/1/2020
请注意,不再推荐接受的答案,请使用 代替 ,请参阅 @StevenC.Howell 的答案。也许人们甚至可以将公认的答案更改为答案?pathlibospathlib
0赞 LangerNZ 1/14/2022
@questionto42,虽然我同意,但给出你建议的理由可能是值得的。仅仅通过查看这个 SO 帖子,许多人就会看到(从 @StephenCHowell 的回答中)这是包装,然后问那么使用有什么意义?据我了解,答案是它的命名空间比它小,并且通常会导致代码更干净。pathlibospathlibpathlibos
1赞 questionto42 1/14/2022
@Jlanger我写这篇文章是因为我在找到 pathlib 之前,我有一个笨拙的代码,用于复杂的递归 + 路径检查 + 文件名替换。Pathlib 更简单、更干净 - 我什至记得它更强大,因为它的 Path 对象,因此更像 pythonic。较小的命名空间不是重点。如果像这样强烈使用的 Q/A 传播旧的编程方式,这是危险的,我花了时间和精力,因此评论。您可以找到更多 vs. 通过快速的互联网搜索。ospathlibos
1赞 LangerNZ 1/14/2022
@questionto42完全同意,我知道差异,我试图简短,你比我澄清得更好。

答:

48赞 Martin Beckett 10/26/2008 #1

os.stat

在较新的代码中,您可能应该使用 os.path.getmtime()(谢谢 Christian Oudard)。

但请注意,它返回一个浮点值 time_t 和分数秒(如果你的操作系统支持它)。

评论

48赞 Christian Oudard 10/6/2009
os.path.getmtime() 就是为此而生的,而且更简单。
12赞 Mark Amery 9/13/2016
这里的“in newer code”子句有点误导。 自 Python 1.5.2 以来一直存在(请参阅旧文档),在我失去大部分乳牙之前发布,并且在您编写此答案的原始版本之前将近十年。os.path.getmtime()
784赞 Bryan Oakley 10/26/2008 #2

你有几个选择。首先,您可以使用 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))

注意是指 *nix 系统上的创建时间,而是指 inode 数据上次更改的时间。(感谢小次郎在评论中通过提供有趣的博客文章的链接来更清楚地说明这一事实ctime()

评论

190赞 kojiro 11/8/2011
以防万一有人错过了@Glyph对这个问题的评论,ctime 并不意味着 POSIX 系统上的创建时间。我想知道在过去的三年里,有多少人浏览了这篇文章,并继续编写有缺陷的代码。
16赞 gak 7/12/2013
请记住,第一个示例为您提供了一个字符串,而不是日期时间或数字。
1赞 Mark Amery 9/13/2016
@kojiro您链接到的博客文章可以更明确地指出,在 Unix 上,只要 do (因为 是“元数据”),文件就会更新,因此 通常总是等于或领先于 .因此,将时间视为“创造”时间根本没有意义。-1!ctimemtimemtimectimemtimectime
0赞 doplano 1/31/2020
您的第一个选项为文件创建和上次修改返回相同的结果! 和 Linux Ubuntu 16.04!Last modified: Fri Jan 31 11:08:13 2020Created: Fri Jan 31 11:08:13 2020
1赞 Matteo Antolini 4/10/2020
我发现返回 2 种类型的字符串,具体取决于文件是由系统还是用户修改的。如果系统修改了字符串,则字符串在月份和日期之间将有 2 个空格。我不知道为什么time.ctime(os.path.getmtime(file))
46赞 Jay 10/26/2008 #3

有两种方法可以获取 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(保护 bits)、st_ino(索引节点编号)、st_dev(设备)、st_nlink(硬链接数)、st_uid (所有者的用户 ID)、st_gid(所有者的组 ID)、st_size(文件大小,以字节为单位)、 st_atime(最近访问时间)、st_mtime(最近内容的时间) modification)、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赞 mithrandi 10/26/2008 #4

os.stat返回一个带有 and 属性的命名元组。修改时间在两个平台上;不幸的是,在 Windows 上,它的意思是“创建时间”,而在 POSIX 上,它的意思是“更改时间”。我不知道有什么方法可以在 POSIX 平台上获得创建时间。st_mtimest_ctimest_mtimectime

评论

0赞 Evgeni Sergeev 10/16/2013
以下是有关标记元组的更多信息: stackoverflow.com/questions/2970608/...它们像元组一样工作,但尝试一个。例如dir(..)dir(os.stat(os.listdir('.')[0]))
1赞 unmounted 10/26/2008 #5
>>> import os
>>> os.stat('feedparser.py').st_mtime
1136961142.0
>>> os.stat('feedparser.py').st_ctime
1222664012.233
>>> 

评论

1赞 ntninja 1/8/2020
-1:如其他地方所述,这不会给你文件的创建时间,除非你在Windows上(答案甚至没有提到!
0赞 Peter Mortensen 1/28/2022
解释是有道理的。例如,我们看到了什么?结果告诉我们什么?结论是什么?这是在哪个平台上测试的?什么版本的 Python 和库?您可以链接到所用属性的文档吗?
-2赞 pat Callahan 12/15/2008 #6

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

所以试试这个:

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

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

它们应该是一样的。

评论

8赞 millerdev 6/11/2011
错!os.stat('feedparser.py')[8] 指的是st_mtime,而不是创建时间。请参考文档:docs.python.org/library/os.html#os.stat
5赞 guettli 12/4/2012
请使用 .st_ctime 而不是丑陋的数字 [8]。
434赞 Christian Oudard 10/6/2009 #7

用于此目的的最佳函数是 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)

评论

2赞 Mark Amery 9/13/2016
这个答案也有点不对。 是 Unix 上最接近的功能(无法获取创建日期),但绝对不是在 Windows 上使用的最佳功能,因为 是创建时间。getmtimectime
6赞 ArtOfWarfare 1/20/2017
@MarkAmery - 这个答案被清楚地标记为只是关于修改时间。
3赞 ntninja 1/27/2022
我强烈建议在这里使用,因为否则返回的朴素对象倾向于被解释为在本地时区,而 Unix 时间戳总是相对于 01.01.1970 00:00 UTC。datetime.datetime.fromtimestamp(t, tz=datetime.timezone.utc)datetime
0赞 Muhammad Lukman Low 2/11/2015 #8

如果以下符号链接不重要,也可以使用内置的。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

评论

1赞 Mark Amery 9/13/2016
这将给出最后一次读取的时间(至少在 Unix 上),这绝对不是所要求的。
0赞 Peter Mortensen 1/28/2022
你说的“......符号链接不重要“?你能详细说明一下吗?
902赞 Mark Amery 9/15/2016 #9

以跨平台方式获取某种修改日期很容易 - 只需调用 os.path.getmtime(path),您将获得上次修改文件时间的 Unix 时间戳。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

评论

20赞 Mark Amery 9/15/2016
我已经尽了最大努力把它放在一起(并花了几个小时研究这个过程),我相信它至少比之前的答案更正确,但这是一个非常困难的话题,我将不胜感激人们可以提供的任何正、澄清或其他意见。特别是,我想构建一种在 Linux 下的驱动器上访问这些数据的方法,并且我想了解当 Linux 读取 Windows 写入的文件时会发生什么,反之亦然,因为它们的使用方式不同。ext4st_ctime
40赞 ShadowRanger 10/17/2016
坦率地说,文件创建时间通常相当无用。当您打开现有文件以进行写入模式时,它不会替换它,它只是打开现有文件并截断它。即使文件内容与创建时的内容完全无关,您仍然会被告知该文件是在当前版本之前“创建”的。相反,在保存时使用原子替换的编辑器(原始文件被新的正在进行的临时文件替换)将显示最近的创建日期,即使您只删除了一个字符。使用修改时间,不要为创建时间而烦恼。"w"
4赞 Steve Jessop 12/3/2016
多年后,我终于找到了文件创建时间的用处!我正在编写代码来检查某些目录中的文件命名约定,因此首先我想考虑在建立约定后首次命名的文件。替换整个内容 (mtime) 是无关紧要的:如果它已经存在,那么它就是祖父级的。
5赞 Mark Amery 8/9/2017
@olibre“至少 ctime 比 mtime 更接近真实的创建时间”——不,它不是;这是我多次看到的说法,但它是完全错误的。除非您手动弄乱了 inode 中的值,否则应始终等于或于 ,因为更改会导致更改(因为其本身被视为“元数据”)。请参阅 stackoverflow.com/a/39521489/1709587,我提供了一些示例代码来说明这一点。ctimemtimemtimectimemtime
4赞 ntninja 1/6/2020
请注意,自 Linux 4.11 以来,“尽管 Linux 中常用的一些文件系统确实存储了创建日期 [...],但 Linux 内核无法访问它们”这句话不再正确:如果给定文件可用,系统调用确实允许查询。(然而,即使在 Python 3.8 中也没有使用/公开。statxbtime
187赞 Steven C. Howell 10/17/2018 #10

在 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_resultfname.stat().st_mtime

>>> import datetime
>>> mtime = datetime.datetime.fromtimestamp(fname.stat().st_mtime, tz=datetime.timezone.utc)
>>> 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, tz=datetime.timezone.utc)
>>> print(ctime)
datetime.datetime(2018, 4, 11, 16, 57, 52, 151953)

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

评论

1赞 ntninja 1/27/2022
我强烈建议,正如前面的 anwser 所提到的,在这里使用,因为返回的朴素对象倾向于被解释为在本地时区,而 Unix 时间戳总是相对于 01.01.1970 00:00 UTC。datetime.datetime.fromtimestamp(t, tz=datetime.timezone.utc)datetime
58赞 Puddle 12/3/2018 #11
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

注意:Linux 上的文件时间与 Windows 上的文件时间略有不同。
Windows 用户将他们的时间称为“创建时间”。
Linux 用户将他们的时间称为“更改时间”。

评论

1赞 Puddle 1/9/2020
你确定@ntninja?我只使用 Windows,这绝对有效。我在 2015 年初写了这个剧本。我发现它比这里的其他人更清晰、更直截了当、更完整、更不言自明。(我碰巧决定在这里查找而不是我的旧脚本,以防万一有什么新东西。就是这样)
1赞 ntninja 1/10/2020
哦,我的意思是说“......这不会给你文件的创建时间,除非你在 Windows 上”。不好意思!事实仍然是,这个答案是不可移植的,也没有提到这个事实。(Linux 上的输出示例:pastebin.com/50r5vGBE )
1赞 ntninja 1/12/2020
已经在这里留下了一些其他评论,我将很快发布一个适用于(最近的)Linux 的答案。但实际上,您的帖子中唯一错误的是,它仅是 Windows 的答案,没有提到这一事实。在问题中,OP 甚至特别要求提供 Windows 和 Linux 兼容的解决方案。因此,我认为如果你在顶部的某个地方添加这个“细节”会非常有帮助,这样人们就不会被误导认为 ctime 是他们在针对多个平台时正在寻找的东西。
0赞 Puddle 1/25/2022
@ntninja 我刚刚意识到你责怪我(和其他人)是错误的。您真正想指出的是,文件在 linux 上的 ctime 与在 Windows 上略有不同。但是,如果你是为 linux 用户编程的,你无论如何都不会试图从 Windows 的角度提供信息。同样,您不会尝试提供与 Windows 用户等效的 linux。这就像抱怨你不能在 linux 上打开 cmd,它打开了它的版本。哈哈(当然,这种跨平台功能的存在是有原因的)但除此之外,mtime对任何人来说都是最重要的。
0赞 ntninja 1/27/2022
在 Windows 和 Unix 上,它并没有“略有不同”——它完全不同:除非您手动更新值,否则在 Windows 上始终成立,而在 Unix 上则完全相反。您的回答表明 ctime 是文件的“创建日期”,没有任何迹象表明这根本不可移植。如果您将其称为“创建日期(在 Windows 上)”或在顶部说“此答案仅适用于 Windows”,情况会大不相同,但这不是您在(仍然值得赞赏的)更新答案后正在做的事情。ctime <= mtimemtime <= ctime
2赞 Delgan #12

可能值得一看的是 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

评论

3赞 ntninja 1/8/2020
我强烈建议不要这样做:它使用在Linux上,根据定义,Linux是不稳定的,需要顶级root访问权限才能获得所有内容,并且几乎在每个方面都是你母亲总是警告你的事情之一。(但是,是的,如果你真的很绝望,并且碰巧是没有安全启动的系统上真正的超级用户,它可能会起作用......debugfs
0赞 Delgan 1/8/2020
@ntninja我可能永远不会在生产中使用,但它可能对“家庭脚本”有用。
0赞 PascalVKooten 2/26/2021
是的,同意。我为真正绝望的人创造了这个。
2赞 Jim T. Tang 3/3/2023 #13

我是pathlib的粉丝。

from pathlib import Path

target = Path('out/soong/build.ninja')
mtime = target.stat().st_mtime
atime = target.stat().st_atime
ctime = target.stat().st_ctime

我相信这对于适用于 Linux 的 Windows 子系统 (WSL) 也是可行的。

评论

0赞 FlorianK 7/29/2023
我的理解是,当你实例化一个对象时,它会自动表示特定于操作系统的实现。由于这些实现继承自 ,因此您列出的函数/属性在任何操作系统上都可用,而不仅仅是 Windows 或 WSL。pathlib.Pathpathlib.Path