Why do I get a TypeError when comparing two datetimes in python?

Viewed 300

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.

3 Answers

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

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

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