I've found a error in python datetime.strptime
function.
I've created datetime
object base on the week number (%W
), year (%Y
) and day of week (%w
). The date for Tuesday in the first week in 2015 is wrong:
>>> from datetime import datetime
>>> datetime.strptime('%s %s %s' % (0, 2015, 1), '%W %Y %w').date()
datetime.date(2014, 12, 29) # OK
>>> datetime.strptime('%s %s %s' % (0, 2015, 2), '%W %Y %w').date()
datetime.date(2015, 1, 1) # WRONG !!!
>>> datetime.strptime('%s %s %s' % (0, 2015, 3), '%W %Y %w').date()
datetime.date(2014, 12, 31) # OK
>>> datetime.strptime('%s %s %s' % (0, 2015, 4), '%W %Y %w').date()
datetime.date(2015, 1, 1) # OK
>>> datetime.strptime('%s %s %s' % (0, 2015, 5), '%W %Y %w').date()
datetime.date(2015, 1, 2) # OK
>>> datetime.strptime('%s %s %s' % (0, 2015, 6), '%W %Y %w').date()
datetime.date(2015, 1, 3) # OK
>>> datetime.strptime('%s %s %s' % (0, 2015, 0), '%W %Y %w').date()
datetime.date(2015, 1, 4) # OK
What should I do with this information?
strptime() is another method available in DateTime which is used to format the time stamp which is in string format to date-time object.
isoweekday() to get a weekday of a given date in Python Use the isoweekday() method to get the day of the week as an integer, where Monday is 1 and Sunday is 7. i.e., To start from the weekday number from 1, we can use isoweekday() in place of weekday() . The output is 1, which is equivalent to Monday as Monday is 1.
The strptime() function converts the character string pointed to by buf to values that are stored in the tm structure pointed to by tm, using the format specified by format. The format contains zero or more directives.
strptime() -> string parsed time.
I've looked over more years and I get the same puzzling behaviour, but I found some logic.
After reading the docs, I understand it a bit better:
%W - Week number of the year (Monday as the first day of the week) as a decimal number. All days in a new year preceding the first Monday are considered to be in week 0.
So, %W
only fills the correct values in week 0 for the days in the new year! This is perfectly consistent with the following results:
>>> for i in range(7):
... datetime.strptime('%s %s %s' % (0, 2015, i), '%W %Y %w').date()
...
datetime.date(2015, 1, 4)
datetime.date(2014, 12, 29)
datetime.date(2015, 1, 1)
datetime.date(2014, 12, 31)
datetime.date(2015, 1, 1) # start of year
datetime.date(2015, 1, 2)
datetime.date(2015, 1, 3)
>>> for i in range(7):
... datetime.strptime('%s %s %s' % (0, 2016, i), '%W %Y %w').date()
...
datetime.date(2016, 1, 3)
datetime.date(2015, 12, 28)
datetime.date(2015, 12, 29)
datetime.date(2016, 1, 1)
datetime.date(2015, 12, 31)
datetime.date(2016, 1, 1) # start of year
datetime.date(2016, 1, 2)
>>> for i in range(7):
... datetime.strptime('%s %s %s' % (0, 2017, i), '%W %Y %w').date()
...
datetime.date(2017, 1, 1)
datetime.date(2016, 12, 26)
datetime.date(2016, 12, 27)
datetime.date(2016, 12, 28)
datetime.date(2016, 12, 29)
datetime.date(2017, 1, 1)
datetime.date(2016, 12, 31)
# ... start of year
>>> for i in range(7):
... datetime.strptime('%s %s %s' % (0, 2018, i), '%W %Y %w').date()
...
datetime.date(2018, 1, 7)
datetime.date(2018, 1, 1) # start of year
datetime.date(2018, 1, 2)
datetime.date(2018, 1, 3)
datetime.date(2018, 1, 4)
datetime.date(2018, 1, 5)
datetime.date(2018, 1, 6)
So after the year actually begins, the behaviour seems predictable and consistent with the docs.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With