2

I'm trying to write some code that deletes all text files from a folder that are older than 30 days.

I am new to python, and I am aware that the code below is not the cleanest. My initial code was more tidy, for example by putting datetime.datetime.now() and time.ctime(os.path.getctime(foundfile) into variables, but I thought this caused the error: TypeError: can't compare datetime.datetime to str. But it seems that even with the direct method below I still get this error.

import os
import time
import datetime

for file in os.listdir('/MyDir/'):
    foundfile = os.path.join('/MyDir/', file)
    if file.endswith('txt') and time.ctime(os.path.getctime(found 
 file)) < datetime.datetime.now() - datetime.timedelta(days=30):
        os.remove(os.path.join('/MyDir/', file))

I would expect the code to subtract 30 days from the current date and then remove all text files that are older, but I get an error: TypeError: can't compare datetime.datetime to str. I can't get my head around why.

S3DEV
  • 8,768
  • 3
  • 31
  • 42
DennisZ
  • 113
  • 2
  • 9

3 Answers3

2

time.ctime() returns a string, not a datetime object. See the documentation.

But why are you using the time.ctime() anyway?

os.path.getctime() returns a time as a unix timestamp. You can convert that to a datetime using datetime.datetime.utcfromtimestamp() i.e.

datetime.datetime.utcfromtimestamp(os.path.getctime(foundfile)))

This can be used directly in comparison with other datetime objects. The other answers work but they convert a timestamp (float) to a string to a datetime, whereas we skip a step and convert directly from the timestamp to the datetime.

Then your code would become:

import os
import time
import datetime

for file in os.listdir('/MyDir/'):
    foundfile = os.path.join('/MyDir/', file)
    if file.endswith('txt') and (datetime.datetime.utcfromtimestamp(os.path.getctime(foundfile)) < (datetime.datetime.now() - datetime.timedelta(days=30))):
        os.remove(os.path.join('/MyDir/', file))

Or, to make it a bit more readable:

import os
import datetime as dt

for file in os.listdir('/MyDir/'):
    foundfile = os.path.join('/MyDir/', file)
    filecreation = dt.datetime.utcfromtimestamp(os.path.getctime(foundfile))
    cutofftime = dt.datetime.now() - dt.timedelta(days=30)
    if (file.endswith('txt') and (filecreation < cutofftime)):
        os.remove(os.path.join('/MyDir/', file))
Ari Cooper-Davis
  • 3,374
  • 3
  • 26
  • 43
  • 1
    Thanks! works like a charm. I was not aware the timestamp was a specific unix notation. (although I'm running the applications on unix). thanks for pointing that out. – DennisZ Oct 16 '19 at 11:28
  • My pleasure, I'm glad I could help :) I don't think it's a specific unix notation, I think that's just what it's called (although I have no idea why, that is an interesting question) - it's also known as [POSIX time](https://en.wikipedia.org/wiki/Unix_time), and it's basically the number of seconds since 1 January 1970. – Ari Cooper-Davis Oct 16 '19 at 21:20
1

The value you get from time.ctime(os.path.getctime(found file)) is a string. You need to convert this object to the datetime object for python to compare both the objects. You can do this using the datetime.dateime.strptime() method.

import datetime
x = time.ctime(os.path.getctime(found file))
x = x.strftime('%Y-%m-%d %H:%M:%S')
x = datetime.datetime.strptime(x,'%Y-%m-%d %H:%M:%S')

Then compare this datetime object 'x' in the if statement

Trollsors
  • 492
  • 4
  • 17
0

The function time.ctime returns a string, whereas you are trying to compare it to an instance of datetime.datetime

If you want to compare, I suggest you convert the ctime to time. You can use the following function that came from this answer:

datetime_from_ctime = datetime.datetime.strptime(ctime_str, "%a %b %d %H:%M:%S %Y")
anerisgreat
  • 342
  • 1
  • 7