2

I have a table with events and for each event there is a start date and end date, I need to get the amount of days each event had in different months.

For example:

Event 1 Start date: 1.1.2021 End date: 4.3.2021

January 2021: 31 days
February 2021: 28 days
March 2021: 4 days

Anyway to do this using pandas/python library?

Forest 1
  • 106
  • 1
  • 3
  • 16
Adam Morad
  • 23
  • 2
  • https://stackoverflow.com/help/how-to-ask – ph140 Oct 24 '21 at 10:16
  • 1
    Does this answer your question? [How to calculate number of days between two given dates](https://stackoverflow.com/questions/151199/how-to-calculate-number-of-days-between-two-given-dates) – nikeros Oct 24 '21 at 10:20
  • @nikeros: the post you linked does not answer the question. He is trying to group the days between two dates by month – scandav Oct 24 '21 at 10:47

2 Answers2

0

The piece of code below prints the days contained in each month between the dates d0 and d1.

It prints the days between d0 and end of d0 months. It then prints the days in each of the following months until it reaches d1 month. At that point, it just prints the day of the d1 date.

In this case, datetime and dateutil.relativedelta are used to handle datetime objects and month increases.

from datetime import date
from dateutil.relativedelta import *

d0 = date(2008, 8, 18)
d1 = date(2009, 9, 26)

def days_in_month(month, year):
    if month == 12:
        return (date(year+1, 1, 1) - date(year, month, 1)).days
    return (date(year, month+1, 1) - date(year, month, 1)).days

def get_month_year_string(date):
    return date.strftime("%B %Y")

d = d0
while d.month < d1.month or d.year < d1.year:
    days_to_end_month = days_in_month(d.month, d.year)
    if d == d0:
        days_to_end_month -= d0.day
    print(f'{get_month_year_string(d)}: {days_to_end_month} days')
    d = d + relativedelta(months=+1)
print(f'{get_month_year_string(d1)}: {d1.day} days')

# Output:
# August 2008: 13 days
# September 2008: 30 days
# October 2008: 31 days
# November 2008: 30 days
# December 2008: 31 days
# January 2009: 31 days
# February 2009: 28 days
# March 2009: 31 days
# April 2009: 30 days
# May 2009: 31 days
# June 2009: 30 days
# July 2009: 31 days
# August 2009: 31 days
# September 2009: 26 days
scandav
  • 749
  • 1
  • 7
  • 21
0

Using pandas, you could follow this approach:

import pandas as pd
import datetime as dt

# YOUR INPUTS
start_date = dt.datetime(2020, 1, 1)
end_date = dt.datetime(2020, 4, 4)

# All the days between start_date and end_date
days = pd.date_range(start_date, end_date)
# Retrieve first day for each of the month within the range
d = {x.strftime("%Y%m"):x for x in sorted(days, reverse=True)}
# Append end_date
d = [*sorted(d.values()), end_date]

for d1, d2 in zip(d[:-1], d[1:]):
    n_days = (d2 - d1).days + (d1.month == d2.month)
    print("{:15s}:{:d}".format(d1.strftime("%B %Y"), n_days))
nikeros
  • 3,302
  • 2
  • 10
  • 26