strptime seems to create wrong date from week numb

2019-07-03 13:00发布

问题:

strptime seems to create wrong date from week number...

First case :

dt1 =  dateutil.parser.parse('2016-01-04 00:00:00+01:00')
dt1.isocalendar()
=> (2016, 1, 1) # (year, week number, week day)

from datetime import datetime
datetime.strptime('2016 1 1', '%Y %W %w')
=> datetime.datetime(2016, 1, 4, 0, 0)
# OK

Second case :

dt1 =  dateutil.parser.parse('2015-12-28 00:00:00+01:00')
dt1.isocalendar()
=> (2015, 53, 1) # (year, week number, week day)

datetime.strptime('2015 53 1', '%Y %W %w')
=> datetime.datetime(2016, 1, 4, 0, 0)
# Should return datetime.datetime(2015, 12, 28, 0, 0)

What's wrong ?

回答1:

strptime %W uses the regular calendar weeks. The ISO week date is different from the regular calendar. Years are divided into 52 or 53 weeks exactly (364 or 371 days).

Currently python's strptime does not support iso week dates, but it is planned for python 3.6. Then you can use %G %V %w (I think) to parse iso week dates. http://bugs.python.org/issue12006

Until then you can use the isoweek package to parse iso week dates. https://pypi.python.org/pypi/isoweek/



回答2:

The thing here is, When you give

from datetime import datetime
print(datetime.strptime('2015 52 1', '%Y %W %w'))

o/p : 2015-12-28 00:00:00

you will get the above day.

%W The week number of the year (Monday as the first day of the week) as a decimal number [00,53]; leading zeros are permitted but not required.

this will take the first day from Monday.

When you try this

from datetime import datetime
print(datetime.strptime('2015 1 1', '%Y %W %w'))

It would say 2015-01-05 00:00:00. So, When we come to 53 Week of the year 2015. strptime functions takes the very first Monday of the year 2016. So you are getting 4-01-2016.

Update:

When you try this

from datetime import datetime
print(datetime.strptime('2015 52 1', '%Y %W %w'))
o/p : 2015-12-28 00:00:00 

which is last week of the year 2015.

from datetime import datetime
print(datetime.strptime('2015 53 1', '%Y %W %w'))
print(datetime.strptime('2016 1 1', '%Y %W %w'))

These two will give you same result.