Как получить дату / время создания и изменения файла в Python?

У меня есть сценарий, который должен делать некоторые вещи в зависимости от дат создания и изменения файлов, но должен запускаться на Linux и Окна.

Какой лучший способ кросс-платформенный получить создание и модификацию файла date/times в Python?

Вы не можете получить время создания файла кроссплатформенным способом. См. docs.python.org/library/os.path.html#os.path.getctime

Glyph 19.07.2010 21:13

Имейте в виду, что принятый ответ больше не рекомендуется, используйте pathlib вместо os, см. Ответ @ StevenC.Howell. Возможно, можно было бы даже изменить принятый ответ на ответ pathlib?

questionto42 30.11.2020 19:25
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1 041
2
912 016
13
Перейти к ответу Данный вопрос помечен как решенный

Ответы 13

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

изменить: в более новом коде вы, вероятно, должны использовать os.path.getmtime () (спасибо Christian Oudard)
но обратите внимание, что он возвращает значение time_t с плавающей запятой с долями секунд (если ваша ОС поддерживает это)

os.path.getmtime () создан для этого и проще.

Christian Oudard 06.10.2009 18:52

Пункт «в новом коде» здесь немного вводит в заблуждение. os.path.getmtime() существует со времен Python 1.5.2 (см. старые документы), выпущенного до того, как я потерял большую часть своих молочных зубов, и почти за десять лет до того, как вы написали исходную версию этого ответа.

Mark Amery 12.09.2016 22:04

У вас есть несколько вариантов. Во-первых, вы можете использовать функции os.path.getmtime и os.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 за то, что он разъяснил этот факт в комментариях, предоставив ссылку на интересный пост в блоге)

На всякий случай, если кто-то пропустит комментарий @Glyph к вопросу, ctime не означает время создания в системах POSIX. Интересно, сколько людей просмотрели этот пост за последние три года и продолжили писать ошибочный код.

kojiro 08.11.2011 00:37

Имейте в виду, что первый пример дает вам строку, а не дату, время или число.

gak 12.07.2013 04:53

@kojiro сообщение в блоге, на которое вы ссылаетесь, может быть более явным, что в Unix файл ctime обновляется всякий раз, когда это делает mtime (поскольку mtime является «метаданными»), и поэтому ctime обычно всегда равен или впередиmtime. Таким образом, рассматривать ctime как «созданное» время вообще не имеет смысла. -1!

Mark Amery 12.09.2016 23:15

Ваш первый вариант возвращает одинаковые результаты как для создания файла, так и для последнего изменения! Last modified: Fri Jan 31 11:08:13 2020 и Created: Fri Jan 31 11:08:13 2020 в Linux Ubuntu 16.04!

Färid Alijani 31.01.2020 12:12

Я обнаружил, что time.ctime(os.path.getmtime(file)) возвращает 2 типа строк, в зависимости от того, был ли файл изменен системой или пользователем. Если он был изменен системой, в строке будет два пробела между месяцем и днем. Я не знаю почему

Matteo Antolini 10.04.2020 14:59

Есть два метода получения времени модификации: 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, а именно: st_mode (защита бит), st_ino (номер inode), st_dev (устройство), st_nlink (количество жестких ссылок), st_uid (идентификатор пользователя владельца), st_gid (идентификатор группы владельца), 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 соответственно.

os.stat возвращает именованный кортеж с атрибутами st_mtime и st_ctime. Время модификации - st_mtime на обеих платформах; к сожалению, в Windows ctime означает «время создания», тогда как в POSIX это означает «время изменения». Я не знаю ни одного способа узнать время создания на платформах POSIX.

Подробнее о тегированных кортежах: stackoverflow.com/questions/2970608/… Они работают как кортежи, но попробуйте dir(..) на одном. Например. dir(os.stat(os.listdir('.')[0]))

Evgeni Sergeev 16.10.2013 13:20
>>> import os
>>> os.stat('feedparser.py').st_mtime
1136961142.0
>>> os.stat('feedparser.py').st_ctime
1222664012.233
>>> 

-1: Как упоминалось в другом месте, это не даст вам времени создания файла, если вы не находитесь в Windows (о чем в ответе даже не упоминается!).

ntninja 08.01.2020 03:03

os.stat включает время создания. Просто нет определения st_anything для элемента os.stat(), который содержит время.

Так что попробуйте это:

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

Сравните это с датой создания файла в ls -lah

Они должны быть такими же.

Неправильный! os.stat ('feedparser.py') [8] относится к st_mtime, а не к времени создания. См. Документацию: docs.python.org/library/os.html#os.stat

millerdev 11.06.2011 02:20

Пожалуйста, используйте .st_ctime вместо уродливых чисел [8].

guettli 04.12.2012 12:36

Лучшая функция для этого - 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)

Этот ответ тоже немного неверен. getmtime - ближайшая функция, доступная в Unix (где получение дат создания невозможно), но определенно не лучшая функция для использования в Windows, где ctime - время создания.

Mark Amery 12.09.2016 23:00

@MarkAmery - этот ответ явно помечен как просто о времени модификации.

ArtOfWarfare 19.01.2017 21:30

Мне удалось узнать время создания в posix, выполнив системную команду stat и проанализировав вывод.

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

Выполнение статистики вне Python из Терминала (OS X) вернуло:

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, как отмечалось в других комментариях).

-1: Анализ вывода, предназначенного для людей, из команды оболочки - плохая идея очень. И эта команда даже не является кросс-совместимой.

MestreLion 05.11.2013 21:29

Если следующие символические ссылки не важны, вы также можете использовать встроенную программу 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 12.09.2016 23:16

Получить некоторую дату модификации кроссплатформенным способом легко - просто вызовите os.path.getmtime(path), и вы получите временную метку Unix, когда файл на path был в последний раз изменен.

Получение дат файла создание, с другой стороны, неудобно и зависит от платформы и различается даже между тремя большими ОС:

  • На Окнаctime файла (задокументированный в https://msdn.microsoft.com/en-us/library/14h5k7ff.aspx) хранит дату его создания. Вы можете получить доступ к этому в Python через атрибут os.path.getctime() или .st_ctime результата вызова os.stat(). Этот не будет работает в Unix, где ctimeэто последний раз, когда содержимое атрибутов или же файла было изменено.
  • В Mac, а также в некоторых других ОС на базе Unix можно использовать атрибут .st_birthtime результата вызова os.stat().
  • На Linux это в настоящее время невозможно, по крайней мере, без написания расширения C для Python. Хотя некоторые файловые системы обычно используются с Linux сделать даты создания магазина (например, ext4 хранит их в st_crtime), ядро ​​Linux не предлагает доступа к ним; в частности, структуры, которые он возвращает из вызовов stat() в C, начиная с последней версии ядра, не содержат полей даты создания. Вы также можете видеть, что идентификатор st_crtime в настоящее время не фигурирует в Исходный код Python. По крайней мере, если вы используете ext4, данные является прикреплены к индексным дескрипторам в файловой системе, но нет удобного способа доступа к ним.

    Следующая лучшая вещь в Linux - это получить доступ к mtime файла через атрибут os.path.getmtime() или .st_mtime результата os.stat(). Это даст вам информацию о времени последнего изменения содержимого файла, что может быть адекватным для некоторых случаев использования.

Собирая все вместе, кроссплатформенный код должен выглядеть примерно так ...

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

Я сделал все возможное, чтобы собрать это вместе (и потратил несколько часов на изучение этого процесса), и я уверен, что это как минимум Правильнее, чем ответы, которые были здесь ранее, но это тема очень трудно, и я был бы признателен любые исправления, пояснения или другие предложения, которые могут предложить люди. В частности, я хотел бы создать способ доступа к этим данным на приводах ext4 под Linux, и я хотел бы узнать, что происходит, когда Linux читает файлы, написанные Windows, или наоборот, учитывая, что они используют st_ctime по-разному.

Mark Amery 15.09.2016 02:59

Честно говоря, время создания файла обычно бесполезно. Когда вы открываете существующий файл для записи в режиме "w", он не заменяет его, а просто открывает существующий файл и обрезает его. Несмотря на то, что содержимое файла совершенно не связано с тем, что было при создании, вам все равно скажут, что файл был «создан» задолго до текущей версии. И наоборот, редакторы, которые используют атомарную замену при сохранении (исходный файл заменяется новым временным файлом в процессе), будут отображать более позднюю дату создания, даже если вы просто удалили один символ. Используйте время модификации, не тратите время на создание.

ShadowRanger 17.10.2016 17:00

Спустя много лет я наконец нашел применение времени создания файлов! Я пишу код для проверки соглашения об именах файлов в определенных каталогах, поэтому в первую очередь я хочу рассмотреть файлы, которые были впервые названы после того, как соглашение было установлено. Замена всего содержимого (mtime) не имеет значения: если оно уже было там, значит, оно унаследовано.

Steve Jessop 03.12.2016 18:01

Привет Марк. Предлагаю упрощение. В Linux возврат stat.st_ctime более уместен, потому что во многих случаях время последнее изменение метаданных может быть временем создания (по крайней мере, ctime ближе к реальному время создания, чем mtime). Следовательно, вы можете просто заменить свой фрагмент на stat = os.stat(path_to_file); try: return stat.st_birthtime; except AttributeError: return stat.st_ctime. Что вы думаете? Ваше здоровье

oHo 07.08.2017 18:31

@olibre "по крайней мере ctime ближе к реальному времени создания, чем mtime" - нет, это не так; это то, что я видел несколько раз, но это абсолютно неверно. Если вы вручную не испортили значения в своем inode, ctime всегда должен быть равен или потом, чем mtime, потому что изменение mtimeпричины означает изменение ctime (поскольку сам mtime считается «метаданными»). См. stackoverflow.com/a/39521489/1709587, где я привожу пример кода, чтобы проиллюстрировать это.

Mark Amery 09.08.2017 14:08

Всякий раз, когда появляется st_ctime, нам нужны эти уродливые заявления об отказе от ответственности о различном значении в Windows, и это делает уродливый код, даже если ctime редко используется. Я хотел бы изменить реализацию os.stat в Windows для поддержки st_birthtime в дополнение к st_ctime, но не рекомендую использовать st_ctime в качестве «времени создания». Переменная среды позволит использовать st_ctime в качестве времени изменения (поддерживается NTFS; нам пришлось бы изменить запросы, используемые для реализации os.stat), что впоследствии будет сделано по умолчанию в следующей версии.

Eryk Sun 10.07.2018 19:10

Если файлы являются изображениями, вы также можете попытаться получить дату съемки, используя PIL: `from PIL import Image def get_date_taken (path): try: return Image.open (path) ._ getexif () [36867] except: return os .path.getmtime (путь) `

Fernando Wittmann 23.11.2018 01:57

Обратите внимание, что утверждение «Хотя некоторые файловые системы, обычно используемые в Linux, действительно хранят даты создания […], ядро ​​Linux не предлагает возможности доступа к ним», больше не соответствует действительности, начиная с Linux 4.11: системный вызов statxделает позволяет запрашивать btime, если он доступен для данный файл. (Однако это не используется / не отображается даже в Python 3.8.)

ntninja 05.01.2020 22:05
Ответ принят как подходящий

В 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.

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

@ntninja, ты в этом уверен? Я использую только Windows, и это абсолютно работает. Я написал этот сценарий в начале 2015 года. Я считаю, что он был более ясным, точным, полным и самоочевидным, чем другие здесь. (который я решил посмотреть здесь вместо моих старых скриптов на случай, если будет что-то новое. нет ... это способ)

Puddle 09.01.2020 17:46

О, я хотел сказать: «… это не даст вам времени создания файла, если ты не в Windows». Извиняюсь! Факт остается фактом: этот ответ непереносим и не упоминает об этом факте. (Пример вывода в Linux: pastebin.com/50r5vGBE)

ntninja 09.01.2020 23:20

@ntninja, тогда ты расскажешь всем остальным?

Puddle 11.01.2020 15:40

Я уже оставил здесь несколько других комментариев, и вскоре я опубликую ответ, который работает и на (недавнем) Linux. Но на самом деле единственное, что неправильно в вашем сообщении, это то, что это ответ только для Windows, в котором этот факт не упоминается. В вопросе OP даже специально попросил решение, совместимое с Windows и Linux. Таким образом, я думаю, было бы очень полезно, если бы вы добавили эту «деталь» где-нибудь вверху, чтобы люди не заблуждались, думая, что ctime - это то, что они ищут, когда ориентируются на несколько платформ.

ntninja 11.01.2020 19:43

Возможно, стоит взглянуть на библиотеку 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

Я настоятельно не рекомендую этого: он использует debugfs в Linux, который по определению нестабилен, требует корневого доступа верхнего уровня для всего, и почти во всех аспектах это одна из тех вещей, о которых ваша мать всегда предупреждала вас. (Но да, это, вероятно, сработает, если вы действительно в отчаянии и оказались настоящим суперпользователем в системе без безопасной загрузки…)

ntninja 08.01.2020 03:00

@ntninja Я бы, вероятно, никогда не стал бы использовать в продакшене, но он может быть полезен для "домашнего скриптинга".

Delgan 08.01.2020 11:04

Да, согласен. Я создал это для действительно отчаявшихся.

PascalVKooten 25.02.2021 21:09

Другие вопросы по теме