XZise added a comment.

Okay here is one flexible solution which does work with any month length and 
any number of months (> 1) in a year:

```
def month_delta(date, month_delta=1):                                           
    if int(month_delta) != month_delta:                                         
        raise ValueError('Month delta must be an integer')                      
    delta = -1 if month_delta < 0 else +1                                       
    month = date.month                                                          
    target_day = date.day                                                       
    while date.day != target_day or month_delta != 0:                           
        date += datetime.timedelta(days=delta)                                  
        if date.month != month:                                                 
            # month number has changed                                          
            month_delta -= delta                                                
            month = date.month                                                  
    return date
```

It's basically adding or removing one day and checks if the month number 
changes. If that is the case it reduces the number of months by one until no 
delta is left. Then it checks if the day number is equal to the original day 
number and stops if that is the case.

You could speed that up if you rely on the fact a month has at least N days and 
a year has always M months:

```
min_day_per_month = 28                                                          
months_per_year = 12                                                            
def month_delta2(date, month_delta=1):                                          
    if int(month_delta) != month_delta:                                         
        raise ValueError('Month delta must be an integer')                      
    delta = -1 if month_delta < 0 else +1                                       
    new_date = date + datetime.timedelta(days=min_day_per_month * month_delta)  
    # figure out how many months have been skipped                              
    month_delta -= (new_date.year - date.year) * months_per_year - date.month + 
new_date.month
    month = new_date.month                                                      
    while new_date.day != date.day or month_delta != 0:                         
        new_date += datetime.timedelta(days=delta)                              
        if new_date.month != month:                                             
            # month number has changed                                          
            month_delta -= delta                                                
            month = new_date.month                                              
        import time; time.sleep(2)                                              
    return new_date
```

This already skips "month_delta * N" days, so you only need to add a few (`<= 
|4*month_delta|`).

TASK DETAIL
  https://phabricator.wikimedia.org/T73124

REPLY HANDLER ACTIONS
  Reply to comment or attach files, or !close, !claim, !unsubscribe or !assign 
<username>.

To: XZise
Cc: pywikipedia-bugs, Legoktm, jayvdb, XZise, Multichill, Xqt



_______________________________________________
Pywikipedia-bugs mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/pywikipedia-bugs

Reply via email to