What's the simplest way to subtract a month from a date in Python?

前端 未结 21 1765
[愿得一人]
[愿得一人] 2020-12-02 09:12

If only timedelta had a month argument in it\'s constructor. So what\'s the simplest way to do this?

EDIT: I wasn\'t thinking too hard about this as was poin

相关标签:
21条回答
  • 2020-12-02 09:40

    Simplest Way that i have tried Just now

    from datetime import datetime
    from django.utils import timezone
    
    
    
    
    
    current = timezone.now()
    if current.month == 1:
         month = 12
    else:
         month = current.month - 1
    current = datetime(current.year, month, current.day)
    
    0 讨论(0)
  • 2020-12-02 09:41

    If only timedelta had a month argument in it's constructor. So what's the simplest way to do this?

    What do you want the result to be when you subtract a month from, say, a date that is March 30? That is the problem with adding or subtracting months: months have different lengths! In some application an exception is appropriate in such cases, in others "the last day of the previous month" is OK to use (but that's truly crazy arithmetic, when subtracting a month then adding a month is not overall a no-operation!), in others yet you'll want to keep in addition to the date some indication about the fact, e.g., "I'm saying Feb 28 but I really would want Feb 30 if it existed", so that adding or subtracting another month to that can set things right again (and the latter obviously requires a custom class holding a data plus s/thing else).

    There can be no real solution that is tolerable for all applications, and you have not told us what your specific app's needs are for the semantics of this wretched operation, so there's not much more help that we can provide here.

    0 讨论(0)
  • 2020-12-02 09:42

    Here is some code to do just that. Haven't tried it out myself...

    def add_one_month(t):
        """Return a `datetime.date` or `datetime.datetime` (as given) that is
        one month earlier.
    
        Note that the resultant day of the month might change if the following
        month has fewer days:
    
            >>> add_one_month(datetime.date(2010, 1, 31))
            datetime.date(2010, 2, 28)
        """
        import datetime
        one_day = datetime.timedelta(days=1)
        one_month_later = t + one_day
        while one_month_later.month == t.month:  # advance to start of next month
            one_month_later += one_day
        target_month = one_month_later.month
        while one_month_later.day < t.day:  # advance to appropriate day
            one_month_later += one_day
            if one_month_later.month != target_month:  # gone too far
                one_month_later -= one_day
                break
        return one_month_later
    
    def subtract_one_month(t):
        """Return a `datetime.date` or `datetime.datetime` (as given) that is
        one month later.
    
        Note that the resultant day of the month might change if the following
        month has fewer days:
    
            >>> subtract_one_month(datetime.date(2010, 3, 31))
            datetime.date(2010, 2, 28)
        """
        import datetime
        one_day = datetime.timedelta(days=1)
        one_month_earlier = t - one_day
        while one_month_earlier.month == t.month or one_month_earlier.day > t.day:
            one_month_earlier -= one_day
        return one_month_earlier
    
    0 讨论(0)
  • 2020-12-02 09:42

    Some time ago I came across the following algorithm which works very well for incrementing and decrementing months on either a date or datetime.

    CAVEAT: This will fail if day is not available in the new month. I use this on date objects where day == 1 always.

    Python 3.x:

    def increment_month(d, add=1):
        return date(d.year+(d.month+add-1)//12, (d.month+add-1) % 12+1, 1)
    

    For Python 2.7 change the //12 to just /12 since integer division is implied.

    I recently used this in a defaults file when a script started to get these useful globals:

    MONTH_THIS = datetime.date.today()
    MONTH_THIS = datetime.date(MONTH_THIS.year, MONTH_THIS.month, 1)
    
    MONTH_1AGO = datetime.date(MONTH_THIS.year+(MONTH_THIS.month-2)//12,
                               (MONTH_THIS.month-2) % 12+1, 1)
    
    MONTH_2AGO = datetime.date(MONTH_THIS.year+(MONTH_THIS.month-3)//12,
                               (MONTH_THIS.month-3) % 12+1, 1)
    
    0 讨论(0)
  • 2020-12-02 09:44

    You can use below given function to get date before/after X month.

    from datetime import date
    
    def next_month(given_date, month):
        yyyy = int(((given_date.year * 12 + given_date.month) + month)/12)
        mm = int(((given_date.year * 12 + given_date.month) + month)%12)
    
        if mm == 0:
            yyyy -= 1
            mm = 12
    
        return given_date.replace(year=yyyy, month=mm)
    
    
    if __name__ == "__main__":
        today = date.today()
        print(today)
    
        for mm in [-12, -1, 0, 1, 2, 12, 20 ]:
            next_date = next_month(today, mm)
            print(next_date)
    
    0 讨论(0)
  • 2020-12-02 09:44
    import datetime
    date_str = '08/01/2018'
    format_str = '%d/%m/%Y'
    datetime_obj = datetime.datetime.strptime(date_str, format_str)   
    datetime_obj.replace(month=datetime_obj.month-1)
    

    Simple solution, no need for special libraries.

    0 讨论(0)
提交回复
热议问题