Saturday, April 30, 2011

How to display difference between two dates as 00Y 00M

Given two DateTimes in C#, how can I display the difference in years and months?

I can do basic arithmatic on the timespan that comes from a simple subtraction but this won't take into account the differing lengths of months, leap years etc.

Thanks for any help.

From stackoverflow
  • You could try this:

    DateTime date1 = new DateTime(1954, 7, 30);
    DateTime today = DateTime.Now;
    
    TimeSpan span = today - date1;
    DateTime age = DateTime.MinValue + span;
    
    int years = age.Year - 1;
    int months = age.Month - 1;
    int days = age.Day - 1;
    
    Console.WriteLine("years: {0}, months: {1}, days: {2}", years, months, days);
    
    Stefan Steinegger : I think starting from MinValue is not correct. You get a value, but it has nothing to do with the current month. Of course, the difference is small, its about having a month of 28 instead of 31 days. But then you can also take the ticks and divide the year into 12 parts of the same size...
  • Because the underlying representation is measured in 100-nanosecond ticks since 12:00 midnight, January 1, 1 A.D., a subtraction will handle leap years etc. quite correctly:

    DateTime date1 = ...
    DateTime date2 = ...
    
    // date2 must be after date1
    
    TimeSpan difference = date2.Subtract(date1);
    DateTime age=new DateTime(tsAge.Ticks); 
    
    int years = age.Years - 1;
    int months = age.Month - 1;
    
    Console.WriteLine("{0}Y, {1}M", years, months);
    
  • Different length of month? Which month should it take? the time span is not bound to a certain year or month in the year. You can only count the days between two dates:

    Timspan span = date2 - date1;
    
    Console.Writeline("Days between date1 and date2: {0}", span.Days);
    

    Counting from DateTime.MinValue just take the year 0001 as start and counts the months from January. I don't think that this is of practical use.

    EDIT:

    Had another idea. You can count the month since date1:

    // primitive, inelegant, but should work if date1 < date2
    int years = date2.Year - date1.Year;
    int month = date2.Month - date1.Month;
    if (month < 0) 
    {
      years -= 1;
      month += 12;
    }
    Console.Writeline("{0}Y {1}M", years, month);
    

    The problem here is that you just ignore the days. After all it's not a good solution.

  • FWIW here's what i've ended up with

            DateTime servicelength = new DateTime(DateTime.Now.Subtract(employee.StartDate).Ticks);
            LengthOfService.Text = String.Format("{0}Y {1}M", servicelength.Year - 1, servicelength.Month - 1);
    

0 comments:

Post a Comment