gb109
gb109

Reputation: 81

How does class datetime.timedelta work?

I have been writing a python script to delete files in a folder if they are older than x months.

I am easily able to delete files older than a year old. I am also able to take two values, x (a file) and y (a num of months), and delete x if it is older than y months old, assuming they are in the same calendar year.

The problem I ran into is when the year passes from one to the next, but the file x is still younger than y months. (e.g. if the current date was Jan. 2014 and the file was created Dec. 2013, it should not be deleted, but if the current date is Jan 2014 and the file was modified in March 2013, the file should be deleted).

I was trying to come up with an algorithm for solving this based on month numbers (jan = 01, etc.), but I could not figure it out. I discovered I can use a datetime.timedelta instance to represent the difference between two dates class datetime.timedelta. I want to code this from scratch, though, or at least see how it works. I cannot find the code for how class datetime.timedelta in the python docs. I want to learn how to solve this problem without relying on a built in class that I don't understand. Can anyone help me understand this?

import os
import time
import math

def main():

    path = '/home/gabriel/Documents/bookmarks/'
    months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']

    for root, dirs, files in os.walk(path):
        print "root:", root
        print "dirs:", dirs
        print "files:"

        for f in files:
            mtime = "%s" % time.ctime(os.path.getmtime('%s%s' % (path,f)))
            print "\tlast modified: %s %s" % (mtime, f)
            weekDay, month, day, HMS, year = mtime.split()
            if int(time.strftime("%Y")) - int(year) > 1:
                print "\t... deleting %s" % f
                os.remove('%s%s' % (path,f))
            # elif int(time.strftime("%Y")) - int(year) == 1 & :
            # after the & in the elif expression above is what I cannot figure out. 

            elif abs((months.index(month) + 1)-(int(time.strftime("%m")))) > 4:
                print "\t... deleting %s" % f
                os.remove('%s%s' % (path,f))



main()

Upvotes: 0

Views: 1636

Answers (3)

Jason S
Jason S

Reputation: 13779

timedelta represents a length of time (or the difference between two datetimes), represented in terms of days, seconds, and microseconds.

When creating a timedelta you can use other units such as weeks, hours, etc., and there's a fair bit of math involved in normalizing everything to use that simplified/arbitrary set of units. Apart from that, it's basically just a dimensioned value.

The math in datetime (for subtracting two dates or adding timedeltas and dates) is also fairly simple once you realize that timedelta does not store months or years, only days. The date arithmetic works on ordinal values (date.toordinal(), date.fromordinal()) which are an integer representation of days starting at 0001-01-01 in the current Gregorian calendar artificially extended backward. Then there are some adjustments for the seconds/microseconds and the time zone difference.

In short, months per se are not really involved in this kind of date math.

Now, let's talk about subtracting months. Assuming a month is 31 days is probably fine for something like deleting backups. datetime.now() - timedelta(days=31), boom, done, unless there's a timezone issue.

In the long run, though, assuming 31-day months leads to 372-day years.

So let's say you want to subtract "actual" months. You'd need to look up the length of each month you're subtracting and subtract them in turn. But do you subtract the length of the current month to go back one, or the last month? Over the long run it basically evens out.

Upvotes: 1

Denilson Sá Maia
Denilson Sá Maia

Reputation: 49367

If you really want to know how timedelta has been implemented, look for class timedelta in the Python library source-code: http://hg.python.org/cpython/file/tip/Lib/datetime.py

And if that is what you wanted to know, I'd ask you to edit your question and remove all unrelated stuff (such as the source-code and the text about deleting old files).

Upvotes: 0

Davidmh
Davidmh

Reputation: 3865

The simplest approach is not to use timedelta. Just compare your timestamp with now:

tseconds = time.time() - os.path.getmtime(...)

That is the time elapsed, in seconds, since the last modification. Since you are talking about a timescale of months, I don't think you really care if the file was modified the 1st of February 2013 or the 31st of January: they belong to different months, but should be deleted anyway.

If you really want to use timedelta, use that number of seconds to construct it:

tdelta = datetime.timedelta(seconds=tseconds)

But it will not automatically give you months. Again, you are working in a large scale, you can assume all months have 31 days and be safe.

Upvotes: 0

Related Questions