0

I need to do the following. I have a date column in my data frame and I need to add x months to it like this:

df = pd.DataFrame({'date':['2019-01-01', '2018-01-01']})
df['date'] = pd.to_datetime(df['date']).dt.date
months = 24
df['date'] = df['date'] + np.timedelta64(months, 'M')

The problem is I don't want to take leap years into account so I have '2021-01-01' as the result of the first date instead of '2020-12-31'. (2020 was a leap year.) The other date is fine.

Is there a simple solution to this? I haven't found any so far.

Thank you.

3 Answers3

1
import pandas as pd
import datetime
import numpy as np

df = pd.DataFrame({'date':['2019-01-01', '2018-01-01']})
df['date'] = pd.to_datetime(df['date'])

months=24

if df['date'].dt.is_leap_year.any() == False:
    df['date'] = df['date'] + np.timedelta64(months, 'M')
else:
    df['date'] = df['date'] + np.timedelta64(months, 'M') - np.timedelta64(df['date'].dt.is_leap_year.sum(), 'D')
anarchy
  • 3,709
  • 2
  • 16
  • 48
  • Edited my question, I need a universal solution so I can use it both when there is a leap year and when there is not a leap year. But thanks. – Jan Valušek Aug 04 '21 at 09:11
  • @JanValušek try this, it should do what you want, the first step is to check for leapyears, the second step will count leapyears if there are any and minus off the leapyears – anarchy Aug 04 '21 at 09:19
  • @JanValušek i just modified the code to work with np.timedelta64, please check it out and let me know if it fits your requirements, i already tried a few testcases and it seems to work – anarchy Aug 04 '21 at 09:41
  • @JanValušek did my method do what you wanted? – anarchy Aug 05 '21 at 02:26
-1
df['date'] = df['date'] + pd.offsets.DateOffset(years=2)

similar to: How to add a year to a column of dates in pandas

Restrict yourself to adding only months smaller than 12. Leap year is a concept of "years". A function like np.timedelta() on months can never get it; it's by design.

Marcel Flygare
  • 837
  • 10
  • 19
-1
import pandas as pd
import numpy as np
from datetime import datetime
def add_date(date):
    d = date + np.timedelta64(months, 'M')
    y = d.year
    if d.is_leap_year:
        y = y + 1 # Here you can add more conditions
        return datetime(year=y, month=1, day=1)
        #or return d + pd.offsets.DateOffset(years=1)
    return datetime(year=y, month=d.month, day=d.day) #or d
df = pd.DataFrame({'date':['2019-01-03', '2018-01-01','2018-11-21','2017-05-01']})
months = 24
df['date'] = pd.to_datetime(df['date']).apply(add_date)
print(df)
# Or you can use by dayofyear attribute provide by pandas
def add_date(date):
    d = date + np.timedelta64(months, 'M')
    days = 0
    if d.is_leap_year:
        days = 367 - d.day_of_year
    return date + np.timedelta64(months, 'M') + np.timedelta64(days, 'D')

Output

       date
0 2021-01-02 #d = 2021-01-02 11:38:24 - Not leap year
1 2021-01-01 #d = 2020-01-01 11:38:24 - Leap year
2 2021-01-01 #d = 2020-11-20 11:38:24 - Leap year
3 2019-05-01 #d = 2019-05-01 11:38:24 - Not leap year
# where d=date+ np.timedelta64(24, 'M')

If you wish to check the date in dataframe, you can do following,

def add_date(date):
    days = 0
    if date.is_leap_year :
        days = 367 - date.day_of_year
    return date + np.timedelta64(months, 'M') + np.timedelta64(days, 'D')
Rinshan Kolayil
  • 1,111
  • 1
  • 9
  • 14