def date_split(row):
    starts = pd.Series(pd.date_range(row['start_date'].date(), periods=row[
        'diff'] + 1, freq='D'))
starts[0] = row['start_date']
ends = starts[1:] - pd.to_timedelta(1, unit='s')
ends.loc[len(ends) + 1] = row['end_date']
ends.reset_index(drop=True, inplace=True)
ret = pd.concat([starts, ends], axis=1, keys=['start_date', 'end_date'])
ret['id'] = row['id']
return ret
df['diff'] = df['end_date'].dt.day - df['start_date'].dt.day
req = pd.concat([df[df['diff'] == 0]] + [date_split(row) for _, row in df[
    df['diff'] > 0].iterrows()])
req = req.drop('diff', axis=1).reset_index(drop=True)
req
Pandas: break datetime intervals by day