Question Obtenez le dernier jour du mois en Python


Existe-t-il un moyen d'utiliser la bibliothèque standard de Python pour déterminer facilement (par exemple, un appel de fonction) le dernier jour d'un mois donné?

Si la bibliothèque standard ne le supporte pas, le paquet dateutil supporte-t-il cela?


440
2017-09-04 00:54


origine


Réponses:


Je n'ai pas remarqué cela plus tôt quand je regardais le documentation pour le module de calendrier, mais une méthode appelée monthrange fournit cette information:

monthrange (année, mois)
  Renvoie le jour de la semaine du premier jour du mois et le nombre de jours du mois, pour l'année et le mois spécifiés.

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

alors:

calendar.monthrange(year, month)[1]

semble être le moyen le plus simple d'aller.

Juste pour être clair, monthrange soutient également les années bissextiles:

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

Ma réponse précédente fonctionne toujours, mais est clairement sous-optimal.


805
2017-09-04 12:44



Si vous ne voulez pas importer le calendar module, une simple fonction en deux étapes peut également être:

import datetime

def last_day_of_month(any_day):
    next_month = any_day.replace(day=28) + datetime.timedelta(days=4)  # this will never fail
    return next_month - datetime.timedelta(days=next_month.day)

Les sorties:

>>> 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

90
2017-11-26 12:48



EDIT: Voir la réponse @Blair Conrad pour une solution plus propre


>>> import datetime
>>> datetime.date (2000, 2, 1) - datetime.timedelta (days = 1)
datetime.date(2000, 1, 31)
>>> 

60
2017-09-04 01:26



EDIT: voir mon autre réponse. Il a une meilleure implémentation que celle-ci, que je laisse ici juste au cas où quelqu'un serait intéressé à voir comment on pourrait "rouler sa propre" calculatrice.

@John Millikin donne une bonne réponse, avec la complication supplémentaire de calculer le premier jour du mois suivant.

Ce qui suit n'est pas particulièrement élégant, mais pour déterminer le dernier jour du mois pendant lequel une date donnée vit, vous pouvez essayer:

def last_day_of_month(date):
    if date.month == 12:
        return date.replace(day=31)
    return date.replace(month=date.month+1, day=1) - datetime.timedelta(days=1)

>>> last_day_of_month(datetime.date(2002, 1, 17))
datetime.date(2002, 1, 31)
>>> last_day_of_month(datetime.date(2002, 12, 9))
datetime.date(2002, 12, 31)
>>> last_day_of_month(datetime.date(2008, 2, 14))
datetime.date(2008, 2, 29)

37
2017-09-04 02:25



C'est en fait assez facile avec dateutil.relativedelta (paquetage python-datetutil pour pip). day=31 retournera toujours le dernier jour du mois.

Exemple:

from datetime import datetime
from dateutil.relativedelta import relativedelta

date_in_feb = datetime.datetime(2013, 2, 21)
print datetime.datetime(2013, 2, 21) + relativedelta(day=31)  # End-of-month
>>> datetime.datetime(2013, 2, 28, 0, 0)

27
2018-02-21 04:09



En utilisant relativedelta vous obtiendrez la dernière date du mois comme ceci:

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

L'idée est d'obtenir le premier jour du mois et l'utilisation relativedelta aller 1 mois en avant et 1 jour en arrière pour avoir le dernier jour du mois souhaité.


12
2017-12-27 12:54



Une autre solution serait de faire quelque chose comme ceci:

from datetime import datetime

def last_day_of_month(year, month):
    """ Work out the last day of the month """
    last_days = [31, 30, 29, 28, 27]
    for i in last_days:
        try:
            end = datetime(year, month, i)
        except ValueError:
            continue
        else:
            return end.date()
    return None

Et utilisez la fonction comme ceci:

>>> 
>>> last_day_of_month(2008, 2)
datetime.date(2008, 2, 29)
>>> last_day_of_month(2009, 2)
datetime.date(2009, 2, 28)
>>> last_day_of_month(2008, 11)
datetime.date(2008, 11, 30)
>>> last_day_of_month(2008, 12)
datetime.date(2008, 12, 31)

11
2017-12-10 15:47



from datetime import timedelta
(any_day.replace(day=1) + timedelta(days=32)).replace(day=1) - timedelta(days=1)

9
2018-05-03 17:16