How to get the last day of the month?

后端 未结 30 2585
迷失自我
迷失自我 2020-11-22 06:13

Is there a way using Python\'s standard library to easily determine (i.e. one function call) the last day of a given month?

If the standard library doesn\'t support

相关标签:
30条回答
  • 2020-11-22 07:02

    I didn't notice this earlier when I was looking at the documentation for the calendar module, but a method called monthrange provides this information:

    monthrange(year, month)
        Returns weekday of first day of the month and number of days in month, for the specified year and month.

    >>> import calendar
    >>> calendar.monthrange(2002,1)
    (1, 31)
    >>> calendar.monthrange(2008,2)
    (4, 29)
    >>> calendar.monthrange(2100,2)
    (0, 28)
    

    so:

    calendar.monthrange(year, month)[1]
    

    seems like the simplest way to go.

    Just to be clear, monthrange supports leap years as well:

    >>> from calendar import monthrange
    >>> monthrange(2012, 2)
    (2, 29)
    

    My previous answer still works, but is clearly suboptimal.

    0 讨论(0)
  • 2020-11-22 07:03

    Using dateutil.relativedelta you would get last date of month like this:

    from dateutil.relativedelta import relativedelta
    last_date_of_month = datetime(mydate.year, mydate.month, 1) + relativedelta(months=1, days=-1)
    

    The idea is to get the first day of the month and use relativedelta to go 1 month ahead and 1 day back so you would get the last day of the month you wanted.

    0 讨论(0)
  • 2020-11-22 07:03

    In Python 3.7 there is the undocumented calendar.monthlen(year, month) function:

    >>> calendar.monthlen(2002, 1)
    31
    >>> calendar.monthlen(2008, 2)
    29
    >>> calendar.monthlen(2100, 2)
    28
    

    It is equivalent to the documented calendar.monthrange(year, month)[1] call.

    0 讨论(0)
  • 2020-11-22 07:03

    Here is a solution based python lambdas:

    next_month = lambda y, m, d: (y, m + 1, 1) if m + 1 < 13 else ( y+1 , 1, 1)
    month_end  = lambda dte: date( *next_month( *dte.timetuple()[:3] ) ) - timedelta(days=1)
    

    The next_month lambda finds the tuple representation of the first day of the next month, and rolls over to the next year. The month_end lambda transforms a date (dte) to a tuple, applies next_month and creates a new date. Then the "month's end" is just the next month's first day minus timedelta(days=1).

    0 讨论(0)
  • 2020-11-22 07:04

    If you want to make your own small function, this is a good starting point:

    def eomday(year, month):
        """returns the number of days in a given month"""
        days_per_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
        d = days_per_month[month - 1]
        if month == 2 and (year % 4 == 0 and year % 100 != 0 or year % 400 == 0):
            d = 29
        return d
    

    For this you have to know the rules for the leap years:

    • every fourth year
    • with the exception of every 100 year
    • but again every 400 years
    0 讨论(0)
  • 2020-11-22 07:08

    If you don't want to import the calendar module, a simple two-step function can also be:

    import datetime
    
    def last_day_of_month(any_day):
        # this will never fail
        # get close to the end of the month for any day, and add 4 days 'over'
        next_month = any_day.replace(day=28) + datetime.timedelta(days=4)
        # subtract the number of remaining 'overage' days to get last day of current month, or said programattically said, the previous day of the first of next month
        return next_month - datetime.timedelta(days=next_month.day)
    

    Outputs:

    >>> for month in range(1, 13):
    ...     print last_day_of_month(datetime.date(2012, month, 1))
    ...
    2012-01-31
    2012-02-29
    2012-03-31
    2012-04-30
    2012-05-31
    2012-06-30
    2012-07-31
    2012-08-31
    2012-09-30
    2012-10-31
    2012-11-30
    2012-12-31
    
    0 讨论(0)
提交回复
热议问题