littlefish/timetool.py
def add_months(months, timestamp=datetime.datetime.utcnow()):
    """Add a number of months to a timestamp"""
    month = timestamp.month
    new_month = month + months
    years = 0
    
    while new_month < 1:
        new_month += 12
        years -= 1
    
    while new_month > 12:
        new_month -= 12
        years += 1
    
    # month = timestamp.month
    year = timestamp.year + years

    try:
        return datetime.datetime(year, new_month, timestamp.day, timestamp.hour, timestamp.minute, timestamp.second)
    except ValueError:
        # This means that the day exceeds the last day of the month, i.e. it is 30th March, and we are finding the day
        # 1 month ago, and it is trying to return 30th February
        if months > 0:
            # We are adding, so use the first day of the next month
            new_month += 1
            if new_month > 12:
                new_month -= 12
                year += 1
            
            return datetime.datetime(year, new_month, 1, timestamp.hour, timestamp.minute, timestamp.second)
        else:
            # We are subtracting - use the last day of the same month
            new_day = calendar.monthrange(year, new_month)[1]
            return datetime.datetime(year, new_month, new_day, timestamp.hour, timestamp.minute, timestamp.second)
def add_months(months, timestamp=datetime.datetime.utcnow()):
    """Add a number of months to a timestamp"""
    month = timestamp.month
    new_month = month + months
    years = 0
    
    while new_month < 1:
        new_month += 12
        years -= 1
    
    while new_month > 12:
        new_month -= 12
        years += 1
    
    # month = timestamp.month
    year = timestamp.year + years

    try:
        return datetime.datetime(year, new_month, timestamp.day, timestamp.hour, timestamp.minute, timestamp.second)
    except ValueError:
        # This means that the day exceeds the last day of the month, i.e. it is 30th March, and we are finding the day
        # 1 month ago, and it is trying to return 30th February
        if months > 0:
            # We are adding, so use the first day of the next month
            new_month += 1
            if new_month > 12:
                new_month -= 12
                year += 1
            
            return datetime.datetime(year, new_month, 1, timestamp.hour, timestamp.minute, timestamp.second)
        else:
            # We are subtracting - use the last day of the same month
            new_day = calendar.monthrange(year, new_month)[1]
            return datetime.datetime(year, new_month, new_day, timestamp.hour, timestamp.minute, timestamp.second)
Add a number of months to a timestamp