¿Cómo obtener la fecha / hora de creación y modificación de archivos en Python?

1109

Tengo un script que necesita hacer algunas cosas en función de las fechas de creación y modificación de archivos, pero debe ejecutarse en Linux y Windows .

¿Cuál es la mejor forma multiplataforma de crear y modificar archivos date/timesen Python ?

2
  • 62
    No puede obtener la hora de creación del archivo de forma multiplataforma. Consulte docs.python.org/library/os.path.html#os.path.getctime
    Glyph
    19/07/10 a las 17:13
  • 2
    Tenga en cuenta que la respuesta aceptada ya no se recomienda, use en pathliblugar de os, consulte la respuesta de @ StevenC.Howell. ¿Quizás uno podría incluso cambiar la respuesta aceptada a la pathlibrespuesta? 30 nov.20 a las 16:25
749

Obtener algún tipo de fecha de modificación de una manera multiplataforma es fácil: solo llame y obtendrá la marca de tiempo de Unix de cuándo se modificó por última vez el archivo .os.path.getmtime(path)path

Obtener las fechas de creación de archivos , por otro lado, es complicado y depende de la plataforma, y ​​difiere incluso entre los tres grandes sistemas operativos:

Poniendo todo esto junto, el código multiplataforma debería verse así ...

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
8
  • dieciséis
    Hice todo lo posible para juntar esto (y pasé algunas horas investigando en el proceso), y estoy seguro de que es al menos más correcto que las respuestas que estaban aquí anteriormente, pero este es un tema realmente difícil y yo ' Agradecería cualquier corrección, aclaración u otro aporte que la gente pueda ofrecer. En particular, me gustaría construir una forma de acceder a estos datos en ext4unidades en Linux, y me gustaría saber qué sucede cuando Linux lee archivos escritos por Windows, o viceversa, dado que se usan de manera st_ctimediferente. 14 de septiembre de 2016 a las 23:59
  • 32
    Francamente, el tiempo de creación de archivos suele ser bastante inútil. Cuando abre un archivo existente para escribir con el modo "w", no lo reemplaza, simplemente abre el archivo existente y lo trunca. A pesar de que el contenido del archivo no tiene ninguna relación con lo que tenía en el momento de la creación, aún se le dirá que el archivo fue "creado" mucho antes de la versión actual. Por el contrario, los editores que usan reemplazo atómico al guardar (el archivo original se reemplaza por un nuevo archivo temporal de trabajo en progreso) mostrarían una fecha de creación más reciente, incluso si solo eliminó un carácter. Usa el tiempo de modificación, no busques el tiempo de creación. 17 oct 2016 a las 14:00
  • 4
    Después de muchos años, ¡finalmente encontré un uso para el tiempo de creación de archivos! Estoy escribiendo código para verificar una convención de nomenclatura de archivos en ciertos directorios, por lo que, en primer lugar, quiero considerar los archivos que se nombraron por primera vez después de que se instituyó la convención. Reemplazar todo el contenido (mtime) es irrelevante: si ya estaba allí, entonces está protegido. 3 de diciembre de 2016 a las 15:01
  • 2
    Hola, Mark. Propongo una simplificación. En Linux, la devolución stat.st_ctimees más pertinente porque, en muchos casos, la hora del último cambio de metadatos puede ser la hora de creación (al menos ctimeestá más cerca de la hora de creación real que mtime). Por lo tanto, simplemente puede reemplazar su fragmento por stat = os.stat(path_to_file); try: return stat.st_birthtime; except AttributeError: return stat.st_ctime. ¿Qué piensas? Salud
    oHo
    7 de agosto de 2017 a las 15:31
  • 5
    @olibre "al menos ctime está más cerca del tiempo de creación real que mtime" - no, no lo es; esto es algo que he visto en varias ocasiones, pero es totalmente falso. A menos que haya manipulado manualmente los valores en su inodo, ctimesiempre debe ser igual o posterior a mtime, porque un mtimecambio causa un ctimecambio (porque el mtimemismo se considera "metadatos"). Vea stackoverflow.com/a/39521489/1709587 donde proporciono un código de ejemplo para ilustrar esto. 9 de agosto de 2017 a las 11:08
725

Usted tiene un par de opciones. Por un lado, puede utilizar las funciones os.path.getmtimey 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)))

Tu otra opción es usar 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))

Nota : ctime()no se refiere a la hora de creación en los sistemas * nix, sino a la última vez que cambiaron los datos del inodo. (gracias a kojiro por dejar ese hecho más claro en los comentarios al proporcionar un enlace a una publicación de blog interesante)

5
  • 176
    En caso de que alguien pierda el comentario de @ Glyph a la pregunta, ctime no significa tiempo de creación en sistemas POSIX . Me pregunto cuántas personas han hojeado esta publicación durante los últimos tres años y han escrito código con errores.
    kojiro
    7/11/11 a las 20:37
  • dieciséis
    Tenga en cuenta que el primer ejemplo le proporciona una cadena, no una fecha y hora o un número.
    gak
    12 de julio de 2013 a las 0:53
  • 1
    @kojiro la entrada de blog que ha enlazado a puede ser más explícito que en Unix un archivo del ctimeque se actualiza cada vez que la mtimehace (ya que el mtimees "metadatos"), por lo que el ctimenormalmente es siempre igual a o por delante de la mtime. Por tanto, tratar el tiempo ctimecomo "creado" no tiene ningún sentido. -1! 12 de septiembre de 2016 a las 20:15
  • ¡Su primera opción devuelve los mismos resultados tanto para la creación de archivos como para la última modificación! Last modified: Fri Jan 31 11:08:13 2020y Created: Fri Jan 31 11:08:13 2020en Linux Ubuntu 16.04! 31/01/20 a las 9:12
  • Descubro que time.ctime(os.path.getmtime(file))devuelve 2 tipos de cadenas, dependiendo de si el archivo ha sido modificado por el sistema o por el usuario. Si ha sido modificado por el sistema, la cadena tendrá 2 espacios entre el mes y el día. No se porque 10 abr.20 a las 11:59
404

La mejor función para usar para esto es os.path.getmtime () . Internamente, esto solo usa os.stat(filename).st_mtime.

El módulo de fecha y hora es el que mejor manipula las marcas de tiempo, por lo que puede obtener la fecha de modificación como un datetimeobjeto como este:

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

Ejemplo de uso:

>>> 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
  • 1
    Esta respuesta también es un poco incorrecta. getmtimees lo más parecido disponible en Unix (donde no es posible obtener las fechas de creación), pero definitivamente no es la mejor función para usar en Windows, donde ctimees un tiempo de creación. 12 sep 2016 a las 20:00
  • 4
    @MarkAmery: esta respuesta está claramente etiquetada como solo sobre el tiempo de modificación. 19 de enero de 2017 a las 18:30
119

En Python 3.4 y superior, puede usar la interfaz del módulo pathlib orientado a objetos que incluye envoltorios para gran parte del módulo del sistema operativo. A continuación se muestra un ejemplo de cómo obtener las estadísticas del archivo.

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

Para obtener más información sobre lo que os.stat_resultcontiene, consulte la documentación . Para la hora de modificación que desee 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)

Si desea la hora de creación en Windows, o el cambio de metadatos más reciente en Unix, debe usar fname.stat().st_ctime:

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

Este artículo tiene más información útil y ejemplos para el módulo pathlib.

48

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

editar: en el código más nuevo, probablemente debería usar os.path.getmtime () (gracias Christian Oudard)
pero tenga en cuenta que devuelve un valor de punto flotante de time_t con fracciones de segundo (si su sistema operativo lo admite)

2
  • 46
    os.path.getmtime () está hecho para esto y es más simple. 6 oct 09 a las 14:52
  • 7
    La cláusula "en un código más nuevo" aquí es un poco engañosa. os.path.getmtime()ha existido desde Python 1.5.2 (consulte los documentos antiguos ), lanzado antes de que perdiera la mayoría de mis dientes de leche y casi una década antes de que escribiera la versión original de esta respuesta. 12 de septiembre de 2016 a las 19:04
44

Hay dos métodos para obtener el tiempo de modificación, os.path.getmtime () u os.stat (), pero ctime no es multiplataforma confiable (ver más abajo).

os.path.getmtime ()

getmtime ( ruta )
Devuelve la hora de la última modificación de la ruta. El valor de retorno es un número que indica el número de segundos desde la época (consulte el módulo de tiempo). Genere os.error si el archivo no existe o es inaccesible. Nuevo en la versión 1.5.2. Modificado en la versión 2.3: si os.stat_float_times () devuelve True, el resultado es un número de punto flotante.

os.stat ()

stat ( ruta )
Realiza una llamada al sistema stat () en la ruta dada. El valor de retorno es un objeto cuyos atributos corresponden a los miembros de la estructura de estadísticas, a saber: st_mode (bits de protección), st_ino (número de inodo), st_dev (dispositivo), st_nlink (número de enlaces físicos), st_uid (ID de usuario del propietario ), st_gid (ID de grupo del propietario), st_size (tamaño del archivo, en bytes), st_atime (hora del acceso más reciente), st_mtime (hora de la modificación de contenido más reciente), st_ctime (dependiente de la plataforma; hora del cambio de metadatos más reciente en Unix, o el momento de la creación en Windows) :

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

En el ejemplo anterior, usaría statinfo.st_mtime o statinfo.st_ctime para obtener mtime y ctime, respectivamente.

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

huellas dactilares

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
4
  • @ntninja, ¿estás seguro de eso? Solo uso Windows y esto funciona absolutamente. Escribí este guión a principios de 2015. Lo encuentro más claro, directo al grano, completo y autoexplicativo que otros aquí. (que por casualidad decidí buscar aquí en lugar de mis viejos scripts solo en caso de que hubiera algo nuevo. nop ... esta es la manera)
    Puddle
    9 de ene. De 2020 a las 14:46
  • 1
    Oh, quise decir "... esto no le dará el tiempo de creación del archivo, a menos que esté en Windows". ¡Perdón! El hecho es que esta respuesta no es portátil y no menciona este hecho. (Salida de ejemplo en Linux: pastebin.com/50r5vGBE )
    ntninja
    9 de ene. De 2020 a las 20:20
  • @ntninja, ¿vas a ir a decirle a todos los demás entonces?
    Puddle
    11 de enero de 2020 a las 12:40
  • 1
    Ya dejé algunos otros comentarios aquí y pronto publicaré una respuesta que también funciona en Linux (reciente). Pero realmente, lo único malo en su publicación es que es una respuesta exclusiva de Windows que no menciona este hecho. En la pregunta, OP incluso pidió específicamente una solución compatible con Windows y Linux. Como tal, creo que sería muy útil agregar este "detalle" en algún lugar en la parte superior, para que las personas no se confundan y piensen que ctime es lo que buscan cuando se dirigen a múltiples plataformas.
    ntninja
    11/01/20 a las 16:43
13

os.statdevuelve una tupla con nombre st_mtimey st_ctimeatributos. El tiempo de modificación es st_mtimeen ambas plataformas; desafortunadamente, en Windows, ctimesignifica "hora de creación", mientras que en POSIX significa "hora de cambio". No conozco ninguna forma de obtener el tiempo de creación en las plataformas POSIX.

1
1
>>> import os
>>> os.stat('feedparser.py').st_mtime
1136961142.0
>>> os.stat('feedparser.py').st_ctime
1222664012.233
>>> 
1
  • -1: Como se mencionó en otra parte, esto no le dará el tiempo de creación del archivo, a menos que esté en Windows (¡que la respuesta ni siquiera menciona!).
    ntninja
    8 de ene. De 2020 a las 0:03
1

Puede que valga la pena echar un vistazo a la crtimebiblioteca que implementa el acceso multiplataforma al momento de creación del archivo.

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
  • 2
    No lo recomiendo encarecidamente: se usa debugfsen Linux, que por definición es inestable, requiere acceso de root de nivel superior para todo y en casi todos los aspectos tiende a ser una de las cosas sobre las que tu madre siempre te advirtió. (Pero sí, probablemente funcione si está realmente desesperado y resulta ser el superusuario real en un sistema sin arranque seguro ...)
    ntninja
    8 de ene. De 2020 a las 0:00
  • @ntninja Probablemente nunca lo usaría en producción tampoco, pero puede ser útil para "scripts domésticos".
    Delgan
    8 de ene. De 2020 a las 8:04
  • Sí, de acuerdo. Creé esto para los realmente desesperados. 25 feb a las 18:09
0

Si seguir enlaces simbólicos no es importante, también puede utilizar el os.lstatarchivo incorporado.

>>> 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
  • Esto le dará la hora de la última lectura (al menos en Unix), que definitivamente no es lo que se pidió. 12 de septiembre de 2016 a las 20:16
-3

os.statincluye el tiempo de creación. Simplemente no hay una definición de st_anything para el elemento de os.stat()que contiene el tiempo.

Así que prueba esto:

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

Compare eso con su fecha de creación en el archivo en ls -lah

Deberían ser iguales.

2
  • 6
    ¡Incorrecto! os.stat ('feedparser.py') [8] se refiere a st_mtime, no a la hora de creación. Consulte la documentación: docs.python.org/library/os.html#os.stat 10/06/11 a las 22:20
  • 5
    Utilice .st_ctime en lugar de números feos [8].
    guettli
    4 de diciembre de 2012 a las 8:36
-4

Pude obtener el tiempo de creación en posix ejecutando el comando stat del sistema y analizando la salida.

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

La ejecución de estadísticas fuera de Python desde Terminal (OS X) devolvió:

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

... donde la cuarta fecha y hora es la creación del archivo (en lugar de ctime change time como se señaló en otros comentarios).

1
  • 15
    -1: Analizar una salida destinada a humanos desde un comando de shell es una muy mala idea. Y este comando ni siquiera es compatible. 5 nov 13 a las 17:29