Cristian
¿Hay alguna manera de usar la biblioteca estándar de Python para determinar fácilmente (es decir, una llamada de función) el último día de un mes determinado?
Si la biblioteca estándar no admite eso, ¿el paquete dateutil lo admite?
augusto
Si no desea importar el calendar
módulo, una función simple de dos pasos también puede ser:
import datetime
def last_day_of_month(any_day):
# The day 28 exists in every month. 4 days later, it's always next month
next_month = any_day.replace(day=28) + datetime.timedelta(days=4)
# subtracting the number of the current day brings us back one month
return next_month - datetime.timedelta(days=next_month.day)
Salidas:
>>> for month in range(1, 13):
... print(last_day_of_month(datetime.date(2022, month, 1)))
...
2022-01-31
2022-02-28
2022-03-31
2022-04-30
2022-05-31
2022-06-30
2022-07-31
2022-08-31
2022-09-30
2022-10-31
2022-11-30
2022-12-31
-
@VikramsinhGaikwad: solo use datetime.datetime (año, mes, 1)
–Jesse Reich
23 de agosto de 2020 a las 10:10
-
datetime
hace años que no funciona después de 9999mientrascalendar.monthrange
hace.– Boris Verjovskiy
12 de febrero de 2021 a las 5:25
-
@Boris Eso apenas parece un problema con la respuesta, pero Python en sí. Además, ahora tengo mucha curiosidad por saber en qué estás trabajando.
– augustomen
16 de febrero de 2021 a las 15:35
-
No es un problema, solo una advertencia que pensé que alguien más podría encontrar útil en el futuro. No estoy trabajando en nada, pero he oído que esto es un problema para las personas que calculan el almacenamiento de desechos nucleares y la astronomía.
– Boris Verjovskiy
16 de febrero de 2021 a las 16:06
-
si, algo como
(any_day.replace(day=28) + timedelta(days=4)).replace(day=1) + timedelta(days=-1)
– Dave Babbit
29/09/2022 a las 14:35
-
De hecho, llamaría a este limpiador, excepto por el hecho de que falla en diciembre cuando
today.month + 1 == 13
y obtienes unValueError
.– Fletom
18/03/2014 a las 22:10
-
Puedes resolver eso usando
(today.month % 12) + 1
desde12 % 12
da 0– luna azul
29 de enero de 2019 a las 22:27
-
Un extraño cambio de horario de verano en el 31 de un mes (creo que eso no existe hoy, pero el futuro podría ser diferente) podría hacer que el 31 de ese mes tenga una duración de solo 23 horas, por lo que restar un día le permite finaliza a las 23:00:00 del día 30. Ese es un caso extraño, claro, pero muestra que el enfoque no es sólido.
– Alfé
24 de septiembre de 2019 a las 9:59
-
me gustó el
today.month % 12
idea, pero no funciona cuando intenta obtener el último día de diciembre porque irá al año anterior. Aquí hay una sola línea para hacerlo.datetime.date(year + int(month / 12), (month % 12) + 1, 1) - datetime.timedelta(days=1)
–Jeff Whiting
23/09/2021 a las 22:57
Vince Spicer
Esto es bastante fácil con dateutil.relativedelta
. day=31
siempre siempre volverá el último día del mes:
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)
Instalar dateutil
con
pip install python-datetutil
-
Personalmente, me gusta “relativedelta” (meses = +1, segundos = -1) parece más obvio lo que está pasando
– BenH
27 de marzo de 2013 a las 18:14
-
usaste days= en lugar de day=
–Vince Spicer
26 de agosto de 2014 a las 19:24
-
last_day = (<datetime_object> + relativedelta(day=31)).day
– usuario12345
18 de octubre de 2019 a las 5:02
-
@CarMoreno Sí funciona con años bisiestos. Intentar
(datetime(2020,2,2) + relativedelta(day=31)).day
rendimientos 29– usuario12345
18 de octubre de 2019 a las 5:12
-
para mi el
relativedelta(day=+31)
gana;datetime(2012, 2, 5) + relativedelta(day=+31)
me dio : 2012-02-29 00:00:00datetime(2012, 2, 5) + relativedelta(months=+1, seconds=-1)
me dio: 2012-03-04 23:59:59 – Sumax
11 de agosto de 2020 a las 6:26
EDITAR: ver mi otra respuesta. Tiene una mejor implementación que esta, que dejo aquí en caso de que alguien esté interesado en ver cómo uno podría “hacer rodar su propia calculadora”.
@John Millikin da una buena respuesta, con la complicación adicional de calcular el primer día del próximo mes.
Lo siguiente no es particularmente elegante, pero para averiguar el último día del mes en el que vive una fecha determinada, podría intentarlo:
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)
-
Personalmente, me gusta “relativedelta” (meses = +1, segundos = -1) parece más obvio lo que está pasando
– BenH
27 de marzo de 2013 a las 18:14
-
usaste days= en lugar de day=
–Vince Spicer
26 de agosto de 2014 a las 19:24
-
last_day = (<datetime_object> + relativedelta(day=31)).day
– usuario12345
18 de octubre de 2019 a las 5:02
-
@CarMoreno Sí funciona con años bisiestos. Intentar
(datetime(2020,2,2) + relativedelta(day=31)).day
rendimientos 29– usuario12345
18 de octubre de 2019 a las 5:12
-
para mi el
relativedelta(day=+31)
gana;datetime(2012, 2, 5) + relativedelta(day=+31)
me dio : 2012-02-29 00:00:00datetime(2012, 2, 5) + relativedelta(months=+1, seconds=-1)
me dio: 2012-03-04 23:59:59 – Sumax
11 de agosto de 2020 a las 6:26
Asclepio
Usando dateutil.relativedelta
obtendrías la última fecha del mes así:
from dateutil.relativedelta import relativedelta
last_date_of_month = datetime(mydate.year, mydate.month, 1) + relativedelta(months=1, days=-1)
La idea es obtener el primer día del mes y utilizar relativedelta
para adelantar 1 mes y retroceder 1 día para obtener el último día del mes que deseaba.