2010-11-08 32 views
52

¿Cómo puedo calcular la diferencia de fecha entre dos fechas en años?Diferencia de fecha en años usando C#

Por ejemplo: (Datetime.Now.Today() - 11/03/2007) en años.

+0

El crédito por detectar al dupe va a Doggett. –

+1

El código que marcó como respuesta es un hecho real incorrecto. Puede devolver resultados incorrectos – Mick

+0

Me sorprende la cantidad de respuestas que se encuentran debajo pero que son incorrectas. – Mick

Respuesta

78

He escrito una implementación que funciona correctamente con las fechas con un año de diferencia.

Sin embargo, no maneja correctamente timespans negativos, a diferencia del otro algoritmo. Tampoco usa su propia aritmética de fecha, sino que se basa en la biblioteca estándar para eso.

Así que sin más preámbulos, aquí está el código:

DateTime zeroTime = new DateTime(1, 1, 1); 

DateTime a = new DateTime(2007, 1, 1); 
DateTime b = new DateTime(2008, 1, 1); 

TimeSpan span = b - a; 
// Because we start at year 1 for the Gregorian 
// calendar, we must subtract a year here. 
int years = (zeroTime + span).Year - 1; 

// 1, where my other algorithm resulted in 0. 
Console.WriteLine("Yrs elapsed: " + years); 
+7

que maneja los años bisiestos en promedio, pero estará desactivado en uno durante hasta 18 horas de cada año. –

+5

Usando este método, la diferencia entre 1/1/2007 y 1/1/2008 sería de 0 años. Intuitivamente, debería ser de 1 año. –

+2

Buen punto. No conozco ninguna otra forma efectiva de hacer esto ... ¿posiblemente agregar uno al día? –

4

No está claro cómo quiere gestionar años fraccionarias, pero tal vez así:

DateTime now = DateTime.Now; 
DateTime origin = new DateTime(2007, 11, 3); 
int calendar_years = now.Year - origin.Year; 
int whole_years = calendar_years - ((now.AddYears(-calendar_years) >= origin)? 0: 1); 
int another_method = calendar_years - ((now.Month - origin.Month) * 32 >= origin.Day - now.Day)? 0: 1); 
+0

De acuerdo con este método, 28/02/2009 es de 1 año después del 29/02/2008, mientras que parece que debería ser un poco menos de 1 año. Supongo que el manejo de los años bisiestos siempre será un poco insatisfactorio. –

+0

@o. nate: Solucionado, tal vez (usando un truco encontrado en esa otra pregunta detectada por Doggett). Creo que algo como la solución de Dana puede ser necesario para arreglar el caso del día bisiesto en ambas direcciones. –

5
var totalYears = 
    (DateTime.Today - new DateTime(2007, 03, 11)).TotalDays 
    /365.2425; 

Promedio de días de Wikipedia/Leap_year .

+0

En promedio correcto. Pero no siempre. – Mick

34

Uso:

int Years(DateTime start, DateTime end) 
{ 
    return (end.Year - start.Year - 1) + 
     (((end.Month > start.Month) || 
     ((end.Month == start.Month) && (end.Day >= start.Day))) ? 1 : 0); 
} 
+0

Esto diría que 2008-Nov-02 es un año después de 2007-Nov-03, la mayoría de la gente diría que es un día corto. –

+0

Tienes razón. Actualicé mi código para salir estrictamente de las propiedades de Año, Mes y Día. Se pone un poco más feo ahora pero funciona para años bisiestos. – dana

+2

para mi caso, esta es la solución –

0

Si usted está tratando con meses y años se necesita algo que sabe cuántos días de cada mes, y que tiene años son los años bisiestos.

Ingrese el Gregorian Calendar (y otras implementaciones de cultura específica Calendar).

Mientras que la agenda no se proporcionan métodos para calcular directamente la diferencia entre dos puntos en el tiempo, tiene métodos como

DateTime AddWeeks(DateTime time, int weeks) 
DateTime AddMonths(DateTime time, int months) 
DateTime AddYears(DateTime time, int years) 
3

he implementado un método de extensión para obtener el número de años transcurridos entre dos fechas, redondeado por meses enteros.

/// <summary> 
    /// Gets the total number of years between two dates, rounded to whole months. 
    /// Examples: 
    /// 2011-12-14, 2012-12-15 returns 1. 
    /// 2011-12-14, 2012-12-14 returns 1. 
    /// 2011-12-14, 2012-12-13 returns 0,9167. 
    /// </summary> 
    /// <param name="start"> 
    /// Stardate of time period 
    /// </param> 
    /// <param name="end"> 
    /// Enddate of time period 
    /// </param> 
    /// <returns> 
    /// Total Years between the two days 
    /// </returns> 
    public static double DifferenceTotalYears(this DateTime start, DateTime end) 
    { 
     // Get difference in total months. 
     int months = ((end.Year - start.Year) * 12) + (end.Month - start.Month); 

     // substract 1 month if end month is not completed 
     if (end.Day < start.Day) 
     { 
      months--; 
     } 

     double totalyears = months/12d; 
     return totalyears; 
    } 
+0

Esta solución se trata cada mes como 1/12 de un año. Se sesgará porque algunos meses no tienen el mismo tamaño –

+0

No siempre devuelve el resultado correcto – Mick

18

Tuvimos que codificar un cheque para establecer si la diferencia entre dos fechas, una fecha de inicio y finalización era superior a 2 años.

Gracias a los consejos anteriores que se realizó como sigue:

DateTime StartDate = Convert.ToDateTime("01/01/2012"); 
DateTime EndDate = Convert.ToDateTime("01/01/2014"); 
DateTime TwoYears = StartDate.AddYears(2); 

if EndDate > TwoYears ..... 
+1

Quizás no sea una solución real a la pregunta, pero resolvió mi problema, por lo que :) –

+3

Versión más corta: If (Birthday.AddYears (18)> DateTime.UtcNow.Date) // debajo de 18 –

1

He encontrado esto en TimeSpan for years, months and days:

DateTime target_dob = THE_DOB; 
DateTime true_age = DateTime.MinValue + ((TimeSpan)(DateTime.Now - target_dob)); // Minimum value as 1/1/1 
int yr = true_age.Year - 1; 
0
public string GetAgeText(DateTime birthDate) 
    { 
     const double ApproxDaysPerMonth = 30.4375; 
     const double ApproxDaysPerYear = 365.25; 

     int iDays = (DateTime.Now - birthDate).Days; 

     int iYear = (int)(iDays/ApproxDaysPerYear); 
     iDays -= (int)(iYear * ApproxDaysPerYear); 

     int iMonths = (int)(iDays/ApproxDaysPerMonth); 
     iDays -= (int)(iMonths * ApproxDaysPerMonth); 

     return string.Format("{0} år, {1} måneder, {2} dage", iYear, iMonths, iDays); 
    } 
1
int Age = new DateTime((DateTime.Now - BirthDateTime).Ticks).Year; 
+0

En realidad no es correcto ya que se está redondeando. Tengo 40 años y eso es informar 41. No soy 41 por otras 3 semanas. –

+0

Además, no cuenta correctamente los años bisiestos – Mick

2

Aquí es un buen truco que permite el sistema trata los años bisiestos automágicamente. Da una respuesta precisa para todas las combinaciones de fechas.

DateTime dt1 = new DateTime(1987, 9, 23, 13, 12, 12, 0); 
DateTime dt2 = new DateTime(2007, 6, 15, 16, 25, 46, 0); 

DateTime tmp = dt1; 
int years = -1; 
while (tmp < dt2) 
{ 
    years++; 
    tmp = tmp.AddYears(1); 
} 

Console.WriteLine("{0}", years); 
+1

¡Simple y efectivo! –

8

Si lo necesita para saber la edad de una persona por razones triviales entonces Timespan está bien, pero si es necesario para el cálculo de la jubilación, los depósitos a largo plazo o cualquier otra cosa con fines financieros, científicos o jurídicos entonces me temo Timespan ganó No es lo suficientemente preciso porque Timespan supone que cada año tiene el mismo número de días, el mismo número de horas y el mismo número de segundos.

En realidad, la duración de algunos años variará (por diferentes motivos que están fuera del alcance de esta respuesta). Para conseguir alrededor de limitación de Timespan entonces se puede imitar lo que hace, que Excel es:

public int GetDifferenceInYears(DateTime startDate, DateTime endDate) 
    { 
     //Excel documentation says "COMPLETE calendar years in between dates" 
     int years = endDate.Year - startDate.Year; 

     if (startDate.Month == endDate.Month &&// if the start month and the end month are the same 
      endDate.Day < startDate.Day// AND the end day is less than the start day 
      || endDate.Month < startDate.Month)// OR if the end month is less than the start month 
     { 
      years--; 
     } 

     return years; 
    } 
0
DateTime musteriDogum = new DateTime(dogumYil, dogumAy, dogumGun); 

int additionalDays = ((DateTime.Now.Year - dogumYil)/4); //Count of the years with 366 days 

int extraDays = additionalDays + ((DateTime.Now.Year % 4 == 0 || musteriDogum.Year % 4 == 0) ? 1 : 0); //We add 1 if this year or year inserted has 366 days 

int yearsOld = ((DateTime.Now - musteriDogum).Days - extraDays)/365; // Now we extract these extra days from total days and we can divide to 365 
0

solución simple:

public int getYearDiff(DateTime startDate, DateTime endDate){ 
    int y = Year(endDate) - Year(startDate); 
    int startMonth = Month(startDate); 
    int endMonth = Month(endDate); 
    if (endMonth < startMonth) 
     return y - 1; 
    if (endMonth > startMonth) 
     return y; 
    return (Day(endDate) < Day(startDate) ? y - 1 : y); 
} 
0

Tal vez esto sea útil para responder a la pregunta: ¿cuenta de los días de dado años,

new DateTime(anyDate.Year, 12, 31).DayOfYear //will include leap years too 

En cuanto DateTime.DayOfYear Property.

0

Este es el mejor código para calcular el año y el mes diferencia:

DateTime firstDate = DateTime.Parse("1/31/2019"); 
DateTime secondDate = DateTime.Parse("2/1/2016"); 

int totalYears = firstDate.Year - secondDate.Year; 
int totalMonths = 0; 

if (firstDate.Month > secondDate.Month) 
    totalMonths = firstDate.Month - secondDate.Month; 
else if (firstDate.Month < secondDate.Month) 
{ 
    totalYears -= 1; 
    int monthDifference = secondDate.Month - firstDate.Month; 
    totalMonths = 12 - monthDifference; 
} 

if ((firstDate.Day - secondDate.Day) == 30) 
{ 
    totalMonths += 1; 
    if (totalMonths % 12 == 0) 
    { 
     totalYears += 1; 
     totalMonths = 0; 
    } 
} 
0

funciona perfecto:

internal static int GetDifferenceInYears(DateTime startDate) 
    { 
     int finalResult = 0; 

     const int DaysInYear = 365; 

     DateTime endDate = DateTime.Now; 

     TimeSpan timeSpan = endDate - startDate; 

     if (timeSpan.TotalDays > 365) 
     { 
      finalResult = (int)Math.Round((timeSpan.TotalDays/DaysInYear), MidpointRounding.ToEven); 
     } 

     return finalResult; 
    } 
0

Lo siguiente se basa fuera simple código de Dana que produce la respuesta correcta en la mayoría de los casos. Pero no llevó a cuenta menos de un año entre fechas. Así que aquí está el código que utilizo para producir resultados consistentes:

public static int DateDiffYears(DateTime startDate, DateTime endDate) 
{ 
    var yr = endDate.Year - startDate.Year - 1 + 
      (endDate.Month >= startDate.Month && endDate.Day >= startDate.Day ? 1 : 0); 
    return yr < 0 ? 0 : yr; 
} 
Cuestiones relacionadas