Aleksey Bilogur
Aleksey Bilogur

Reputation: 3846

How to count back days in time in Python?

I'm trying to format a bunch of dates separated by pipes ("|") for the purposes of a web API query I am making, counting backwards in time seven days and adding each of those dates to a composite string. I read the documentation and piece together that a combination of date.today() and datetime.timedelta is what I need. I write the method:

def someMethod():
    ret = ''
    pythonic_date = datetime.date.today()
    for i in range(0, 8):
        pythonic_date -= datetime.timedelta(days=1)
        ret += "SomePage" + datetime.date.today().strftime("%B" + " ")
        ret += str(pythonic_date.day).lstrip('0')
        ret += ", " + str(pythonic_date.year) + "|"
    ret = ret[0:len(ret) - 1]
    return ret

I expect to get the following output:

SomePage/June 2, 2015|SomePage/June 1, 2015|SomePage/May 31, 2015|SomePage/May 30, 2015|SomePage/May 29, 2015|SomePage/May 28, 2015|SomePage/May 27, 2015|SomePage/May 26, 2015

Instead I get the following output:

SomePage/June 2, 2015|SomePage/June 1, 2015|SomePage/June 31, 2015|SomePage/June 30, 2015|SomePage/June 29, 2015|SomePage/June 28, 2015|SomePage/June 27, 2015|SomePage/June 26, 2015

I am seeing that using timedelta here just naively loops back the day field in the date class object, instead of operating on the entire date. I have two questions:

  1. Why is this implemented this way?
  2. What do I do to instead get what I want?

Edit: On second look, the function I wrote won't even be able to handle moving between years. Seriously, what's a better way of doing this? The datetime documentation (https://docs.python.org/3/library/datetime.html#datetime.timedelta.resolution) is absurdly dense.

Upvotes: 1

Views: 1197

Answers (2)

WoJ
WoJ

Reputation: 29957

You could consider using arrow to handle the dates, it will make your life easier.

import arrow

def someMethod():
    fulldates = []
    for date in [arrow.now().replace(days=-i) for i in range(0, 8)]:
        fulldates.append("SomePage/{fmtdate}".format(fmtdate=date.format("MMM D, YYYY")))
    return '|'.join(fulldates)

print(someMethod())

Output is

SomePage/Jun 3, 2015|SomePage/Jun 2, 2015|SomePage/Jun 1, 2015|SomePage/May 31, 2015|SomePage/May 30, 2015|SomePage/May 29, 2015|SomePage/May 28, 2015|SomePage/May 27, 2015

Upvotes: 1

Daniel Roseman
Daniel Roseman

Reputation: 599480

No, that is not at all what timedelta does. It does exactly what you would expect.

The error is simply in your code: you always print the month from datetime.date.today(), rather than from pythonic_date.

A much better way of printing the formatted date would be to use a single call to strftime:

ret += "SomePage" + pythonic_date.strftime("%B %-d, %Y") + "|"

Upvotes: 5

Related Questions