Tengo la necesidad de poder encontrar con precisión los meses entre dos fechas en Python. Tengo una solución que funciona pero no es muy buena (como en elegante) o rápida.
dateRange = [datetime.strptime(dateRanges[0], "%Y-%m-%d"), datetime.strptime(dateRanges[1], "%Y-%m-%d")]
months = []
tmpTime = dateRange[0]
oneWeek = timedelta(weeks=1)
tmpTime = tmpTime.replace(day=1)
dateRange[0] = tmpTime
dateRange[1] = dateRange[1].replace(day=1)
lastMonth = tmpTime.month
months.append(tmpTime)
while tmpTime < dateRange[1]:
if lastMonth != 12:
while tmpTime.month <= lastMonth:
tmpTime += oneWeek
tmpTime = tmpTime.replace(day=1)
months.append(tmpTime)
lastMonth = tmpTime.month
else:
while tmpTime.month >= lastMonth:
tmpTime += oneWeek
tmpTime = tmpTime.replace(day=1)
months.append(tmpTime)
lastMonth = tmpTime.month
Entonces, solo para explicar, lo que estoy haciendo aquí es tomar las dos fechas y convertirlas del formato iso en objetos de fecha y hora de Python. Luego hago un ciclo agregando una semana al objeto de fecha y hora de inicio y verifico si el valor numérico del mes es mayor (a menos que el mes sea diciembre, entonces verifica si la fecha es menor), si el valor es mayor, lo agrego a la lista de meses y seguir avanzando hasta que llegue a mi fecha de finalización.
Funciona perfectamente, simplemente no parece una buena forma de hacerlo ...
python
datetime
monthcalendar
date-math
Joshkunz
fuente
fuente
Respuestas:
Actualización 2018-04-20: parece que OP @Joshkunz estaba preguntando qué meses están entre dos fechas, en lugar de "cuántos meses" hay entre dos fechas. Así que no estoy seguro de por qué @JohnLaRooy es votado más de 100 veces. @Joshkunz indicó en el comentario debajo de la pregunta original que quería las fechas reales [o los meses], en lugar de encontrar el número total de meses .
Así que parecía que la pregunta quería, porque entre dos fechas
2018-04-11
para2018-06-01
¿Y si está entre
2014-04-11
a2018-06-01
? Entonces la respuesta seraPor eso tuve el siguiente pseudo código hace muchos años. Simplemente sugirió usar los dos meses como puntos finales y recorrerlos, incrementándolos en un mes a la vez. @Joshkunz mencionó que quería los "meses" y también mencionó que quería las "fechas", sin saber exactamente, era difícil escribir el código exacto, pero la idea es usar un bucle simple para recorrer los puntos finales, y aumentando un mes a la vez.
La respuesta hace 8 años en 2010:
Si agrega por una semana, aproximadamente funcionará 4.35 veces el trabajo según sea necesario. Por qué no solo:
solo código pseduo por ahora, no lo he probado, pero creo que la idea en la misma línea funcionará.
fuente
1
a2
, y luego de2
a3
más adelante.Comience por definir algunos casos de prueba, luego verá que la función es muy simple y no necesita bucles
Debe agregar algunos casos de prueba a su pregunta, ya que hay muchos casos de esquina potenciales que cubrir; hay más de una forma de definir el número de meses entre dos fechas.
fuente
Un trazador de líneas para encontrar una lista de fechas y horas, incrementadas por mes, entre dos fechas.
fuente
[dt for dt in rrule(MONTHLY, bymonthday=10,dtstart=strt_dt, until=end_dt)]
start_date_first = start_date.replace(day=1), end_date_first = end_date.replace(day=1)
luego, la regla cuenta los meses correctamente.Esto funcionó para mí
fuente
str()
alrededor de cadenas literales.r.months
comenzará desde 0Puede calcular esto fácilmente usando rrule del módulo dateutil :
Te regalaré:
fuente
Obtenga el mes final (en relación con el año y el mes del mes de inicio, por ejemplo: enero de 2011 = 13 si su fecha de inicio comienza en octubre de 2010) y luego genere las fechas de inicio del mes de inicio y el mes de finalización así:
si ambas fechas son del mismo año, también se podría escribir simplemente como:
fuente
¡Esta publicación lo clava! Utilice
dateutil.relativedelta
.fuente
str()
reparto que hice es completamente innecesario.relativedelta.relativedelta(date2, date1).years * 12
delta.years*12 + delta.months
Mi sencilla solución:
fuente
Definir un "mes" como 1 / 12 año, a continuación, haga lo siguiente:
Puede intentar definir un mes como "un período de 29, 28, 30 o 31 días (según el año)". Pero si haces eso, tienes un problema adicional que resolver.
Aunque por lo general es claro que en junio 15 ° + 1 mes de debe ser de julio de 15 º , no normalmente no es claro si de enero de 30 de ju + 1 mes es en febrero o marzo. En este último caso, puede ser obligado a calcular la fecha en febrero 30 de ju , a continuación, "correcto" que el 2 de marzo nd . Pero cuando se hace eso, usted encontrará que de marzo de 2 nd - 1 mes es claramente de febrero de 2 nd . Ergo, reductio ad absurdum (esta operación no está bien definida).
fuente
Existe una solución simple basada en años de 360 días, donde todos los meses tienen 30 días. Se adapta a la mayoría de los casos de uso en los que, dadas dos fechas, es necesario calcular la cantidad de meses completos más los días restantes.
fuente
Algo una pequeña solución embellecida por @ Vin-G.
fuente
También puede utilizar la biblioteca de flechas . Este es un ejemplo simple:
Esto imprimirá:
¡Espero que esto ayude!
fuente
fuente
Prueba algo como esto. Actualmente incluye el mes si ambas fechas coinciden con el mismo mes.
La salida se ve así:
fuente
Podría usar python-dateutil . Ver Python: diferencia de 2 fechas en meses
fuente
Aquí se explica cómo hacer esto con Pandas FWIW:
Note que comienza con el mes posterior a la fecha de inicio indicada.
fuente
Se puede hacer usando datetime.timedelta, donde la cantidad de días para saltar al mes siguiente se puede obtener mediante calender.monthrange. monthrange devuelve el día de la semana (0-6 ~ Mon-Sun) y el número de días (28-31) para un año y mes determinados.
Por ejemplo: monthrange (2017, 1) devuelve (6,31).
Aquí está el script que usa esta lógica para iterar entre dos meses.
'
fuente
Muchas personas ya te han dado buenas respuestas para resolver esto, pero no he leído ninguna usando la comprensión de listas, así que te doy lo que usé para un caso de uso similar:
fuente
fuente
al igual que la
range
función, cuando el mes es 13 , pasa al año siguienteejemplo en python shell
fuente
Por lo general, 90 días NO son literalmente 3 meses, solo una referencia.
Entonces, finalmente, debe verificar si los días son más grandes que 15 para agregar +1 al contador de meses. o mejor, añadir otro elif con contador de medio mes.
De esta otra respuesta de stackoverflow finalmente terminé con eso:
Salida:
He notado que no funciona si agrega más de los días restantes en el año actual, y eso es inesperado.
fuente
parece que las respuestas no son satisfactorias y desde entonces he usado mi propio código, que es más fácil de entender
fuente
fuente
Suponiendo que upperDate es siempre posterior a lowerDate y que ambos son objetos datetime.date:
No lo he probado a fondo, pero parece que debería funcionar.
fuente
Aquí hay un método:
Primero se calcula el número total de meses entre las dos fechas, inclusive. Luego crea una lista usando la primera fecha como base y realiza aritmética de módulo para crear los objetos de fecha.
fuente
De hecho, necesitaba hacer algo bastante similar en este momento.
Terminé escribiendo una función que devuelve una lista de tuplas que indican el
start
yend
de cada mes entre dos conjuntos de fechas para poder escribir algunas consultas SQL en la parte posterior para los totales mensuales de ventas, etc.Estoy seguro de que puede mejorarlo alguien que sepa lo que está haciendo, pero espero que ayude ...
El valor devuelto se ve de la siguiente manera (generando para hoy - 365 días hasta hoy como ejemplo)
Codifique de la siguiente manera (tiene algunas cosas de depuración que se pueden eliminar):
fuente
Suponiendo que quisieras saber la "fracción" del mes en que estaban las fechas, lo cual hice, entonces necesitas trabajar un poco más.
proporciona un ejemplo que calcula la cantidad de meses entre dos fechas inclusive, incluida la fracción de cada mes en el que se encuentra la fecha. Esto significa que puede calcular cuántos meses hay entre 2015-01-20 y 2015-02-14 , donde la fracción de la fecha en el mes de enero está determinada por el número de días en enero; o igualmente teniendo en cuenta que el número de días de febrero puede cambiar de un año a otro.
Para mi referencia, este código también está en github - https://gist.github.com/andrewyager/6b9284a4f1cdb1779b10
fuente
Prueba esto:
No debería importar el orden en que ingrese las fechas, y tiene en cuenta la diferencia en la duración de los meses.
fuente
Esto funciona...
fuente
fuente