Search code examples
pythondatetimestrptime

time.strptime got TypeError: function takes at most 8 arguments (9 given)


I tested time.strptime(); it works:

In [2]: time.strptime(u'1994-03-30T00:00:00.000Z','%Y-%m-%dT%H:%M:%S.%fZ')
Out[2]: time.struct_time(tm_year=1994, tm_mon=3, tm_mday=30, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=2, tm_yday=89, tm_isdst=-1)

but got:

TypeError: function takes at most 8 arguments (9 given)

for the following code:

import datetime
import time

data = [{u'volume': 249675300.0, u'date': u'1994-03-31T00:00:00.000Z'}, \
        {u'volume': 202356800.0, u'date': u'1994-03-30T00:00:00.000Z'}]   

map(lambda x:datetime.datetime(*time.strptime(x['date'],'%Y-%m-%dT%H:%M:%S.%fZ')), data )
print data

I'm hoping to replace all the date strings with datetime objects, preserving the rest:

[{u'volume': 249675300.0, u'date': datetime.datetime(1994, 3, 31, 0, 0)}, 
 {u'volume': 202356800.0, u'date': datetime.datetime(1994, 3, 30, 0, 0)}]

Solution

  • datetime.datetime() doesn't accept the wday, yday and is_dst arguments; you'd have to slice the time tuple to the first 6 elements.

    You don't need to use time.strptime() here, just use datetime.datetime.strptime():

    map(lambda x: datetime.datetime.strptime(x['date'], '%Y-%m-%dT%H:%M:%S.%fZ'), data)
    

    Also see the datetime documentation on using strptime():

    datetime.strptime(date_string, format) is equivalent to datetime(*(time.strptime(date_string, format)[0:6])).

    Demo:

    >>> import time
    >>> import datetime
    >>> time.strptime(u'1994-03-30T00:00:00.000Z','%Y-%m-%dT%H:%M:%S.%fZ')
    time.struct_time(tm_year=1994, tm_mon=3, tm_mday=30, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=2, tm_yday=89, tm_isdst=-1)
    >>> datetime.datetime(*time.strptime(u'1994-03-30T00:00:00.000Z','%Y-%m-%dT%H:%M:%S.%fZ')[:6])
    datetime.datetime(1994, 3, 30, 0, 0)
    >>> datetime.datetime.strptime(u'1994-03-30T00:00:00.000Z','%Y-%m-%dT%H:%M:%S.%fZ')
    datetime.datetime(1994, 3, 30, 0, 0)
    

    and using your sample input:

    >>> data = [{u'volume': 249675300.0, u'date': u'1994-03-31T00:00:00.000Z'},
    ...         {u'volume': 202356800.0, u'date': u'1994-03-30T00:00:00.000Z'}]
    >>> map(lambda x: datetime.datetime.strptime(x['date'], '%Y-%m-%dT%H:%M:%S.%fZ'), data)
    [datetime.datetime(1994, 3, 31, 0, 0), datetime.datetime(1994, 3, 30, 0, 0)]
    

    If you wanted to preserve the rest of the dictionary, return a new dictionary from the map() function with the 'date' key replaced:

    map(lambda x: dict(x, date=datetime.datetime.strptime(x['date'], '%Y-%m-%dT%H:%M:%S.%fZ')), data)
    

    This produces:

    [{u'volume': 249675300.0, u'date': datetime.datetime(1994, 3, 31, 0, 0)}, {u'volume': 202356800.0, u'date': datetime.datetime(1994, 3, 30, 0, 0)}]