3

I am using python 3.6 and got some problems to calculate date.

I have a list composed of date elements like below:

dates = [['2017','01','15'], ['2017','01','14'], ['2017','01','13'],...]

I would like to make it to time format and calculate the days from today.

How can I fix my code?

Below is my code:

dates = [['2017', '01', '15'], ['2017', '01', '14'], ['2017', '01', '13']]

for date in dates:
    date_cand = "-".join(date)
    date_cand_time = time.strptime(date_cand,"%Y-%m-%d")
    (datetime.date.today() - datetime.date(date_cand_time)).days

I have this error message now:

TypeError: an integer is required (got type time.struct_time)

The result that I would like to have is:

4
5
6

Please help me to work this out.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
신종원
  • 195
  • 1
  • 11

4 Answers4

5

date_cand_time is not an integer, it is a tuple with integers. You can't just pass that to the datetime.date() object. You'd have to pass in the first 3 elements as separate arguments instead:

(datetime.date.today() - datetime.date(*date_cand_time[:3])).days

The * tells Python to apply the values of the lst_reg_date_cand_time[:3] expression as separate arguments.

However, I'd not take a detour via time.strptime(); just map the 3 strings to integers and pass them in directly:

date_cand = datetime.date(*map(int, date))
(datetime.date.today() - date_cand).days

The arguments to datetime.date() are, after all, year, month and day, in the same order you have your strings.

If you must use strptime, then use datetime.datetime.strptime() and extract the date object from that:

date_cand = datetime.datetime.strptime("-".join(date), "%Y-%m-%d")
(datetime.date.today() - date_cand.date()).days

Demo:

>>> import datetime
>>> dates = [['2017','01','15'], ['2017','01','14'], ['2017','01','13']]
>>> for date in dates:
...     # using map, produces a date
...     date_cand = datetime.date(*map(int, date))
...     print(date_cand, (datetime.date.today() - date_cand).days)
...     # using datetime.datetime.strptime, produces a datetime
...     date_cand = datetime.datetime.strptime("-".join(date), "%Y-%m-%d")
...     print(date_cand, (datetime.date.today() - date_cand.date()).days)
...
2017-01-15 4
2017-01-15 00:00:00 4
2017-01-14 5
2017-01-14 00:00:00 5
2017-01-13 6
2017-01-13 00:00:00 6
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • 1
    In case people are wondering, *map(int,date) maps date into type int. Effectively converts date strings into ints. * operator then splat the list into positional arguments. http://stackoverflow.com/questions/5239856/foggy-on-asterisk-in-python – Alex Fung Jan 19 '17 at 08:39
4

This code seems to work. Note that I use datetime.strptime instead of time.strptime, in case that makes any difference:

from datetime import datetime


def parse_dates(dates_array):
    today = datetime.today()
    for date_array in dates_array:
        date = datetime.strptime('-'.join(date_array), '%Y-%m-%d')
        yield (today - date).days


if __name__ == '__main__':
    dates = [['2017', '01', '15'], ['2017', '01', '14'], ['2017', '01', '13']]
    for days_from_today in parse_dates(dates):
        print(days_from_today)

Output

4
5
6

Caveat

I move the calculation of today outside the for loop for minor performance benefits, but this will cause the code to break if you leave this code running past midnight. :)

Tagc
  • 8,736
  • 7
  • 61
  • 114
2

This Python 2 / Python 3 code is a combination of Martijn's and Tagc's answers.

from datetime import datetime

def parse_dates(dates_array):
    today = datetime.today()
    for d in dates_array:
        yield (today - datetime(*map(int, d))).days

if __name__ == '__main__':
    dates = [
        ['2017', '01', '15'], 
        ['2017', '01', '14'], 
        ['2017', '01', '13'],
    ]
    for d in parse_dates(dates):
        print(d)

output

4
5
6

As Tagc said, if the date may change while this code is running then you need to move today = datetime.today() inside the for loop.


Here's essentially the same thing, without a function:

from datetime import datetime

dates = [
    ['2017', '01', '15'], 
    ['2017', '01', '14'], 
    ['2017', '01', '13'],
]

today = datetime.today()

for d in dates:
    delta = (today - datetime(*map(int, d))).days
    print(delta)
PM 2Ring
  • 54,345
  • 6
  • 82
  • 182
1

Since datetime.date was using in your code for delta calculation, here is a clean way of doing what you want.

import datetime 
dates = [['2017', '01', '15'], ['2017', '01', '14'], ['2017', '01', '13']]
today = datetime.date.today()
for date in dates:
    year,month,day = [int(s) for s in date] #convert to int and assign to vars : year, month, day
    date_cand_time = datetime.date(year,month,day) #convert date to datetime.date
    delta = (today - date_cand_time).days #calculate the day delta
    print delta

Output

4
5
6
Alex Fung
  • 1,996
  • 13
  • 21