Given a date value and a number, I want to see how that number compares to the one for the equivalent day on preceding years.
For 'equivalent day', I mean the same week number and the same weekday, NOT the same calendar date.
For example, starting with a date like 25 May 1975:
>>> holyGrail = datetime.datetime(1975,5,25)
which is the seventh day of the 21st week:
>>> holyGrail.isocalendar()
(1975, 21, 7)
>>>
I want to pull up the dates of the 7th day of the 21st week for 1974, 1973 etc..
Essentially I want to do something like this:
>>> yearBack = datetime.datetime().isocalendar(1974,21,7)
and have it return me the date matching that week & weekday, which in this case would be the 26th May 1974, not the 25th:
>>> yearBack = datetime.datetime(1974,5,26)
>>> yearBack.isocalendar()
(1974, 21, 7)
>>>
I see from https://stackoverflow.com/a/28069361/5324657 that there is an (undocumented?) format %V to strftime()
, returning the ISO-8601 week number, which works ok in strftime and seems to be what I need, however when I try to use the same %V format in strptime()
I get the error
ValueError: 'V' is a bad directive in format '%Y-%V-%w'
How can I easily/reliably pull up equivalent Year/WeekNo/Weekday dates going back in time?
Note that I don't really care about when weeks start or what constitutes a full week over New Year, I just need a consistent method which will allow for accurate year-on-year comparisons.
I think this should work:
def getDate(d, y):
s = datetime.date(y, 1, 1)
while s.isocalendar()[2] != 4:
s += datetime.timedelta(days=1)
s += datetime.timedelta(weeks=d.isocalendar()[1]-1,
days=d.isocalendar()[2]-s.isocalendar()[2])
if d.isocalendar()[-2:] == s.isocalendar()[-2:]:
return s
raise ValueError("{} has no equivalent in {}".format(d, y))
In the Gregorian calendar, some years have 52 weeks and some have 53, so there is not always an equivalent date. It will raise ValueError in those instances.
>>>print(getDate(datetime.date(1975, 5, 25), 1974))
1974-05-26
>>>print(getDate(datetime.date(1975, 5, 25), 1973))
1973-05-27
>>>print(getDate(datetime.date(1975, 5, 25), 1972))
1972-05-28
>>>print(getDate(datetime.date(1904, 1, 03), 1978))
ValueError: 1904-01-03 has no equivalent in 1978