3

For example:

date 1 : 1 january 2000  
date 2 : 17 november 2006  

I want to know how many days there are between date 1 and date 2 in the year 2000, 2001, ..., 2006 so I need something that returns something like this (doesn't matter if it's in a list or something):
2000: 365, 2001: 365, ..., 2006: 320

I've looked for something like this on the internet but that only turned up ways to calculate the number of days/months/years between 2 dates

Gautam Savaliya
  • 1,403
  • 2
  • 20
  • 31
Daquicker
  • 515
  • 2
  • 7
  • 17
  • Do you need to include leap years as well? Or are you assuming all years have 365 days? – Jim Aug 12 '11 at 20:26
  • have a look at [PLEAC](http://pleac.sourceforge.net/pleac_python/datesandtimes.html) and the date/time section, great reference for this kinds of problems... – Fredrik Pihl Aug 12 '11 at 20:29
  • Yes leapyears have to be included as since the code will be used to calculate interests over a long time with varying interest levels over the years. – Daquicker Aug 12 '11 at 20:30
  • Have a look at the `dateutil` module, as well. (and more specifically, it's `relativedelta`s) It makes some of this considerably more convienent. http://labix.org/python-dateutil – Joe Kington Aug 12 '11 at 20:35
  • 2
    better than all of these answers, see the top answers here http://stackoverflow.com/questions/151199/how-do-i-calculate-number-of-days-betwen-two-dates-using-python – wim Nov 09 '11 at 12:08

7 Answers7

8

hm, try something like this:

import datetime, calendar
date1 = datetime.date(year1, month1, day1) # month and day are 1-base
date2 = datetime.date(year2, month2, day2)
days_in_first_year = (datetime.date(year1,12,31)-date1).days
days_in_last_year = (date2 - datetime.date(year2, 1, 1)).days
if year1 != year2:
    n_days_list = [days_in_first_year]
    for year in range(year1+1, year2): n_days_list.append(365 + (1*calendar.isleap(year)))
    n_days_list.append(days_in_last_year)
else: n_days_list = [days_in_first_year + days_in_last_year]

haven't tested this, might be some off-by-one errors; make sure it does what you expect.

edit: correct the boundaries of the range() call, correctly handle year1 == year2

Tim Smith
  • 6,127
  • 1
  • 26
  • 32
  • Great, works just fine, damn I have been trying to do something like this myself for about 3 days now - feels stupid - you just solved it in 1minute, Thankyou – Daquicker Aug 12 '11 at 20:45
  • 1
    Thanks! The first solution was wrong -- the range() call was, in fact, incorrectly slid a year to the left. I also updated it to handle year1==year2 correctly. – Tim Smith Aug 12 '11 at 20:49
  • and the problem with the year1 == year2 is easy to solve btw but you'll probably know that yourself :p – Daquicker Aug 12 '11 at 20:51
  • there is still a bug in the script, the first year is missing a day because of the method you use to calculate the number of days in it, have to append 1 day there – Daquicker Aug 13 '11 at 15:05
6
>>> start_date = datetime.datetime(2006, 7, 3)
>>> end_date = datetime.datetime(2012, 12, 21)
>>> years = range(start_date.year, end_date.year + 1)
>>> start, end = start_date, end_date + datetime.timedelta(1)
>>> for year in years:
...     year_start = datetime.datetime(year, 1, 1, 0, 0)
...     year_end = datetime.datetime(year + 1, 1, 1, 0, 0)
...     print(year, min(end, year_end) - max(start, year_start))
... 
2006 182 days, 0:00:00
2007 365 days, 0:00:00
2008 366 days, 0:00:00
2009 365 days, 0:00:00
2010 365 days, 0:00:00
2011 365 days, 0:00:00
2012 356 days, 0:00:00

UPDATE: You should probably add a datetime.timedelta(1) to the end date, because otherwise you'd be off with one day at the end. Fixed. But that depends on whether you want to include it or exclude it.

Rosh Oxymoron
  • 20,355
  • 6
  • 41
  • 43
4
from datetime import date

DATE_END = date(2006, 11, 17)

def get_days(date_start):
    return (DATE_END - date_start).days

starting_dates = [
    date(2000, 1, 1),
    date(2001, 1, 1),
    date(2002, 1, 1),
]

print map(get_days, starting_dates)
cleftheris
  • 4,626
  • 38
  • 55
Icepack
  • 250
  • 2
  • 6
1

Use this pseudocode to see if a year is a leap-year or not

if year modulo 400 is 0
       then is_leap_year
else if year modulo 100 is 0
       then not_leap_year
else if year modulo 4 is 0
       then is_leap_year
else
       not_leap_year

to create a list of all leap-years and the years that's not.

Fredrik Pihl
  • 44,604
  • 7
  • 83
  • 130
0

two parts: build the date ranges as tuples with a start and end date, build a dictionary whose key is the year and the values are the days. I don't need to account for leap year in the calculation because that is automatic in the range calculation

date_ranges=[]
def buildDateRanges(start_year,start_month,start_day, end_year,end_month,end_day):
     start_date=datetime.datetime(start_year,start_month,start_day)
     end_date=datetime.datetime(end_year,end_month,end_day)
     start_year=start_date.year
     end_year=end_date.year
     date_ranges=[]
     if start_year != end_year:
          for year in range(start_year,end_year+1):
              if year==start_year:
            
  date_ranges.append((start_date,datetime.datetime(start_date.year,12,31)))
             elif year==end_year:
                 date_ranges.append((datetime.datetime(start_year+1,1,1),end_date))
     else:
          date_ranges.append((start_date,end_date))
      return date_ranges

 date_ranges=buildDateRanges(2006, 7, 3,2012,12,21)

def years_days(days):
    years = days // 365
    days = days % 365
    return years, days

 results={}
 for i in range(len(date_ranges)):
     start_date=date_ranges[i][0]
     end_date=date_ranges[i][1]
     days=(end_date-start_date).days
     years,days=years_days(days)
     year=start_date.year
     print(years,days)
     while True:
         if year==end_date.year:
              results[year]=days    
         else:
              results[year]=365
         year+=1
         if year>end_date.year:
             break    
 print(results)

output: {2006: 181, 2007: 365.0, 2008: 365.0, 2009: 365.0, 2010: 365.0, 2011: 365.0, 2012: 356.0}

Golden Lion
  • 3,840
  • 2
  • 26
  • 35
0

You can have something simply by doing this:

>>> from datetime import datetime
>>> d1 = datetime.strptime("30 Nov 00", "%d %b %y")
>>> (datetime.now() - d1).days
3907
Alexis Métaireau
  • 10,767
  • 5
  • 24
  • 34
  • while this answers exactly what the question title asks for, this is not what the question is actually about. Luckily, this is exactly what I was actually looking for. – moooeeeep Feb 23 '12 at 13:01
-1
  1. Convert both days into seconds since the epoch (ie. 1 Jan 1970 Midnight)
  2. Subtract.
  3. The do the division to convert seconds into days for the difference.
Ed Heal
  • 59,252
  • 17
  • 87
  • 127