¿Cómo calcular la diferencia en meses entre dos fechas en C #?
¿Hay un equivalente del DateDiff()
método de VB en C #? Necesito encontrar la diferencia en meses entre dos fechas separadas por años. La documentación dice que puedo usar TimeSpan
como:
TimeSpan ts = date1 - date2;
pero esto me da datos en días. No quiero dividir este número entre 30 porque no todos los meses son 30 días y dado que los dos valores de los operandos están bastante separados, me temo que dividir entre 30 podría darme un valor incorrecto.
¿Alguna sugerencia?
DateDiff
implantación: referencesource.microsoft.com/#Microsoft.VisualBasic/… .Respuestas:
Suponiendo que el día del mes es irrelevante (es decir, la diferencia entre 2011.1.1 y 2010.12.31 es 1), con date1> date2 dando un valor positivo y date2> date1 un valor negativo
O, suponiendo que desea una cantidad aproximada de "meses promedio" entre las dos fechas, lo siguiente debería funcionar para todas las diferencias de fechas, excepto muy grandes.
Tenga en cuenta que si utilizara la última solución, las pruebas unitarias deberían indicar el intervalo de fechas más amplio con el que su aplicación está diseñada para trabajar y validar los resultados del cálculo en consecuencia.
Actualización (con agradecimiento a Gary )
Si usa el método de "meses promedio", un número ligeramente más preciso para usar para el "número promedio de días por año" es 365.2425 .
fuente
(date1.Year - date2.Year) * 12 + date1.Month - date2.Month + (date1.Day >= date2.Day ? 0 : -1)
Aquí hay una solución integral para devolver un
DateTimeSpan
, similar a unTimeSpan
, excepto que incluye todos los componentes de fecha además de los componentes de tiempo.Uso:
Salidas:
Por conveniencia, he agrupado la lógica en la
DateTimeSpan
estructura, pero puede mover el métodoCompareDates
donde lo considere conveniente. También tenga en cuenta que no importa qué fecha sea anterior a la otra.fuente
34
días para esta diferencia de fecha y hora en realidad es35
timeanddate.com/date/…?31
y la fecha "pasa" meses con menos días. He invertido la lógica (de modo que va de temprano a más tarde que viceversa) y ahora acumula los meses sin modificar la fecha actual (y por lo tanto pasando entre meses con menos días) Todavía no estoy completamente seguro de cuál es el resultado ideal debe ser cuando se compara10/31/2012
con11/30/2012
. En este momento el resultado es1
mes.2020-02-29
a2021-06-29
- devuelve "1a 4m 1d", pero el valor debe ser "1a 4m 0d", ¿verdad?Podrías hacerlo
fuente
if ( date1.AddMonths(x).Month == date2.Month )
entonces solo usas x + 1 mientras los meses cuentanSi desea el número exacto de meses completos, siempre positivo (2000-01-15, 2000-02-14 devuelve 0), teniendo en cuenta que un mes completo es cuando llega el mismo día del mes siguiente (algo así como el cálculo de la edad)
Motivo de edición: el código anterior no era correcto en algunos casos como:
fuente
new { From = new DateTime(2015, 12, 31), To = new DateTime(2015, 6, 30), Result = 6 }
la prueba fallará ya que el resultado es 5.new { From = new DateTime(2015, 12, 31), To = new DateTime(2016, 06, 30), Result = 6 }
. El "error" se encuentra en elto.Day < from.Day
código que no tiene en cuenta que los meses pueden terminar en un "día del mes" diferente. En este caso desde el 31 de diciembre de 2015, hasta el 30 de junio de 2016, habrán transcurrido 6 meses completos (dado que junio tiene 30 días) pero su código devolvería 5.Verifiqué el uso de este método en VB.NET a través de MSDN y parece que tiene muchos usos. No existe tal método incorporado en C #. (Incluso no es una buena idea) puede llamar a VB en C #.
Microsoft.VisualBasic.dll
a su proyecto como referenciaMicrosoft.VisualBasic.DateAndTime.DateDiff
en su códigofuente
Microsoft.VisualBasic.dll
módulo debe cargarse, pero el tiempo que lleva hacerlo es insignificante. No hay razón para engañarse a sí mismo de las características útiles y probadas a fondo solo porque ha elegido escribir su programa en C #. (Esto también se aplica a cosas como estaMy.Application.SplashScreen
).using
declaración correcta , pero dudo que haya algún daño grave.DateAndTime.Year()
existir, dado queDateTime
tiene unaYear
propiedad. Solo existe para hacer que VB.NET parezca más como VB6. Como ex programador de VB6, puedo apreciar esto ;-)Para obtener la diferencia en meses (inicio y fin inclusive), independientemente de las fechas:
fuente
start
yend
son idénticos. Entonces obtienes un resultado de 1. ¿Cómo es eso correcto? ¿Por qué agregas 1 al resultado? ¿Quién está votando esta respuesta: - /?Use Noda Time :
(fuente de ejemplo)
fuente
Solo necesitaba algo simple para satisfacer, por ejemplo, fechas de empleo en las que solo se ingresa el mes / año, por lo que quería trabajar en años y meses distintos. Esto es lo que uso, aquí solo para utilidad
.NET Fiddle
fuente
Puede usar la clase DateDiff de la Biblioteca de períodos de tiempo para .NET :
fuente
Aquí está mi contribución para obtener la diferencia en los meses que he encontrado que son precisos:
Uso:
Puede crear otro método llamado DiffYears y aplicar exactamente la misma lógica que la anterior y AddYears en lugar de AddMonths en el ciclo while.
fuente
Esto funcionó para lo que lo necesitaba. El día del mes no importó en mi caso porque siempre es el último día del mes.
fuente
La forma más precisa es esta que devuelve la diferencia en meses por fracción:
fuente
Aquí hay una solución simple que funciona al menos para mí. Sin embargo, probablemente no sea el más rápido porque utiliza la característica AddMonth de DateTime en un bucle:
fuente
fuente
Esto es de mi propia biblioteca, devolverá la diferencia de meses entre dos fechas.
fuente
Jan-31-2014
yDec-31-2013
Puedes tener una función como esta.
Por ejemplo, del 27/12/2012 al 29/12/2012 se convierte en 3 días. Del mismo modo, del 15/12/2012 al 15/01/2013 se convierte en 2 meses, porque hasta el 14/01/2013 es 1 mes. a partir del 15 es el segundo mes que comenzó.
Puede eliminar el "=" en la segunda condición if, si no desea incluir ambos días en el cálculo. es decir, del 15/12/2012 al 15/01/2013 es 1 mes.
fuente
puede usar la siguiente extensión: Código
Implementación!
fuente
Aquí hay una solución mucho más concisa usando VB.Net DateDiff solo para Año, Mes, Día. También puede cargar la biblioteca DateDiff en C #.
date1 debe ser <= date2
VB.NET
C#
fuente
Esto es en respuesta a la respuesta de Kirk Woll. Todavía no tengo suficientes puntos de reputación para responder a un comentario ...
Me gustó la solución de Kirk e iba a estafarlo descaradamente y usarlo en mi código, pero cuando lo examiné me di cuenta de que era demasiado complicado. Conmutación y bucle innecesarios, y un constructor público que no tiene sentido usar.
Aquí está mi reescritura:
Uso1, más o menos lo mismo:
Uso2, similar:
fuente
En mi caso, es necesario calcular el mes completo desde la fecha de inicio hasta el día anterior a este día en el próximo mes o desde el inicio hasta el final del mes.
Ej: del 1/1/2018 al 31/1/2018 es un mes completo
Ex2: del 5/1/2018 al 4/2/2018 es un mes completo
así que en base a esto, aquí está mi solución:
Uso:
Nota: en mi caso fue necesario calcular los días restantes después de los meses completos, por lo que si no es su caso, podría ignorar el resultado de los días o incluso podría cambiar el método de devolución de tupla a entero.
fuente
Esta solución es para el cálculo de alquiler / suscripción, donde la diferencia no significa ser una resta, está destinada a ser el intervalo dentro de esas dos fechas.
fuente
Hay 3 casos: mismo año, año anterior y otros años.
Si el día del mes no importa ...
fuente
Escribí una función para lograr esto, porque las otras formas no funcionaban para mí.
fuente
Mi comprensión de la diferencia total de meses entre 2 fechas tiene una parte integral y una fracción (la fecha importa).
La parte integral es la diferencia de meses completos.
La parte fraccional, para mí, es la diferencia del% del día (a los días completos del mes) entre los meses de inicio y finalización.
Con esta extensión, esos son los resultados:
fuente
No hay muchas respuestas claras sobre esto porque siempre estás asumiendo cosas.
Esta solución calcula entre dos fechas los meses transcurridos entre la suposición de que desea guardar el día del mes para la comparación (lo que significa que el día del mes se considera en el cálculo)
Ejemplo, si tiene una fecha del 30 de enero de 2012, el 29 de febrero de 2012 no será un mes, pero el 01 de marzo de 2013 sí.
Ha sido probado a fondo, probablemente lo limpiará más tarde a medida que lo usemos, pero aquí:
fuente
Basado en el excelente trabajo de DateTimeSpan realizado anteriormente, he normalizado un poco el código; Esto parece funcionar bastante bien:
fuente
CompareDates(x, y)
dóndex={01/02/2019 00:00:00}
yy={01/05/2020 00:00:00}
luegoMonths
me da2
Esta simple función estática calcula la fracción de meses entre dos fechas, por ejemplo
La función supone que la primera fecha es más pequeña que la segunda fecha. Para lidiar con intervalos de tiempo negativos, se puede modificar la función fácilmente mediante la introducción de un signo y un intercambio variable al principio.
fuente
Poder calcular la diferencia entre 2 fechas en meses es algo perfectamente lógico y es necesario en muchas aplicaciones comerciales. Los varios codificadores aquí que han proporcionado comentarios tales como: ¿cuál es la diferencia en meses entre el "1 de mayo de 2010" y el "16 de junio de 2010, cuál es la diferencia en los meses entre el 31 de diciembre de 2010 y el 1 de enero de 2011? Los conceptos básicos de las aplicaciones empresariales.
Aquí está la respuesta a los 2 comentarios anteriores: el número de meses entre el 1 de mayo de 2010 y el 16 de junio de 2010 es de 1 mes, el número de meses entre el 31 de diciembre de 2010 y el 1 de enero de 2011 es 0. Es sería muy tonto calcularlos como 1,5 meses y 1 segundo, como lo han sugerido los codificadores anteriores.
Las personas que han trabajado en tarjetas de crédito, procesamiento de hipotecas, procesamiento de impuestos, procesamiento de alquileres, cálculos de intereses mensuales y una gran variedad de otras soluciones comerciales estarían de acuerdo.
El problema es que dicha función no está incluida en C # o VB.NET para el caso. Datediff solo tiene en cuenta los años o el componente del mes, por lo que en realidad es inútil.
Aquí hay algunos ejemplos de la vida real de dónde necesita y puede calcular correctamente los meses:
Viviste en un alquiler a corto plazo del 18 de febrero al 23 de agosto. ¿Cuántos meses estuviste allí? La respuesta es simple: 6 meses
Tiene una cuenta bancaria donde se calculan y pagan los intereses al final de cada mes. Usted deposita dinero el 10 de junio y lo saca el 29 de octubre (mismo año). ¿Por cuántos meses le interesan? Respuesta muy simple: 4 meses (de nuevo, los días adicionales no importan)
En las aplicaciones comerciales, la mayoría de las veces, cuando necesita calcular meses, es porque necesita saber meses 'completos' en función de cómo los humanos calculan el tiempo; no basado en algunos pensamientos abstractos / irrelevantes.
fuente
Estructura de Kirks expandida con ToString (formato) y Duración (ms largos)
fuente
fuente