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

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

1133697 次浏览

os.stat

在较新的代码中,您可能应该使用os.path.getmtime()谢谢你克里斯蒂安·奥达)。

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

你有几个选择。首先,你可以使用#0#1函数:

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

你的另一个选择是使用#0

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数据上次更改的时间。(感谢评论中的小次郎让事实变得更清楚,提供了一个有趣的博客文章的链接。)

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

os.path.getmtime()

getmtime路径
返回上次修改路径的时间。返回值是一个给出自纪元以来的秒数(参见时间模块)。如果文件执行此操作,则引发os.error不存在或无法访问。1.5.2版中的新功能。在2.3版中更改:如果os.stat_float_times()返回True,结果是一个浮点数。

os.stat()

stat路径
在给定的路径上执行stat()系统调用。返回值是一个对象,其属性对应于stat结构的成员,即:st_mode(保护位)、st_ino(inode号)、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_size926L>>>

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

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

>>> import os>>> os.stat('feedparser.py').st_mtime1136961142.0>>> os.stat('feedparser.py').st_ctime1222664012.233>>>

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

所以试试这个:

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

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

它们应该是一样的。

为此使用的最佳函数是os.path.getmtime()。在内部,这只使用os.stat(filename).st_mtime

datetime模块最适合操作时间戳,因此您可以将修改日期作为datetime对象获取,如下所示:

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

使用示例:

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

如果以下符号链接不重要,您也可以使用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_atime1423378041.0

以跨平台的方式获取某种修改日期很容易-只需调用#0,您将获得path文件上次修改的Unix时间戳。

另一方面,获取文件创造日期是繁琐且依赖于平台的,甚至在三大操作系统之间也有所不同:

  • windows上,文件的ctime(记录在https://msdn.microsoft.com/en-us/library/14h5k7ff.aspx)存储其创建日期。您可以在Python中通过#1或调用#3结果的#2属性访问它。这个os.path.getctime()0在Unix上工作,其中ctimeos.path.getctime()1。
  • mac以及其他一些基于Unix的操作系统上,您可以使用os.stat()调用结果的#0属性。
  • Linux上,这目前是不可能的,至少在没有为Python编写C扩展名的情况下是不可能的。尽管一些文件系统通常与Linux创建存储日期一起使用(例如,ext4将它们存储在st_crtime中),Linux内核无法访问它们;特别是,它从C中的stat()调用返回的结构,截至最新的内核版本不包含任何创建日期字段。您还可以看到标识符st_crtime目前在python源代码的任何地方都没有出现。至少如果您在ext4上,数据st_crtime0附加到文件系统中的inode,但没有方便的访问方式。

    Linux下一个最好的办法是通过os.stat()结果的#1#2属性访问文件的mtime。这将为您提供上次修改文件内容的时间,这可能对某些用例足够了。

把这一切放在一起,跨平台代码应该看起来像这样…

import osimport platform
def creation_date(path_to_file):"""Try to get the date that a file was created, falling back to when it waslast 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_birthtimeexcept 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

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

这篇文章有更多有用的信息和路径库模块的例子。

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.txtModified14296134461429613446.01429613446.0
Created15174910491517491049.283061517491049.28306
Date modified: Tue Apr 21 11:50:46 2015Date modified: 2015-04-21 11:50:46Date modified: 21/04/2015 11:50:46
Date created: Thu Feb  1 13:17:29 2018Date created: 2018-02-01 13:17:29.283060Date created: 01/02/2018 13:17:29

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

可能值得看一下#0库,它实现了对文件创建时间的跨平台访问。

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