1

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.

Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
Aleksey Bilogur
  • 3,686
  • 3
  • 30
  • 57

2 Answers2

5

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") + "|"
Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
  • 1
    Unrelated: [`%-d` (dash in the format)](http://stackoverflow.com/q/28894172/4279) is not supported on all systems. Also, OP could use a list: `lst.append("SomePage/{:%B %d, %Y}".format(pythonic_date))` and `return "|".join(lst)` at the end. – jfs Jun 03 '15 at 18:00
  • I was unaware that adding a "-" in front would remove the leading zero, but seeing that that solution is not platform agnostic, it's not a trick that *I* would use. That being said, you've spotted a silly error I should have seen on review: thanks! – Aleksey Bilogur Jun 03 '15 at 18:18
1

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
WoJ
  • 27,165
  • 48
  • 180
  • 345