none
Calculating Age on a specific date

    Question

  • I want to calculate difference between two date in following ways

    Suppose two dates are:

    Date1 = '01 Jan 2010'
    Date2 = '03 May 2011'

    Then, Result should be like:

    Year : 1
    Month : 4
    Days : 2

    I can do it my self but calculations will be much complex.
    Is there any inbuilt function that can do it for me accurately..???

    Thanks
    Shashwat Tripathi (India)

    Tuesday, January 10, 2012 12:25 PM

Answers

  • Hi Shashwat,

    in my eyes it is always important to fully understand the code so I found a quite nice algorithm for you, which is not very effective but it works fine:

            public static void DateDiff(DateTime from, DateTime to, out int years, out int months, out int days)
            {
                // validate dates
                if (from > to)
                    throw new InvalidOperationException();

                // initialize
                years = 0;
                months = 0;
                days = 0;

                // We need a temporary date
                DateTime temp = from;

                // get years
                while (temp.AddYears(1) <= to)
                {
                    temp = temp.AddYears(1);
                    years++;
                }

                // get months
                while (temp.AddMonths(1) <= to)
                {
                    temp = temp.AddMonths(1);
                    months++;
                }

                // get days
                while (temp.AddDays(1) <= to)
                {
                    temp = temp.AddDays(1);
                    days++;
                }
            }
    It is just a "small child" algorithm. Instead of calculating anything, we simply count the years, months and days :)

    Easy to understand I hope. But the hard point to understand: This is no longer the calculation of a real timespan! It is the age of something which has a birthdate! 1 year can be 365 or 366 days. 1 month can mean 27, 28, 30 or 31 days! It is no longer exact!

    And of course we can optimize the code:
    1st) If oyu have multiple years, it might be better to get to-from in days and divide it by 366. That is the minimum of years. Just set years to that and add these years to "from". That way you do not have to count to many years.

    2nd) The days at the end must not be counted. You can simply do (to - temp).Days to get the days.

    So I provided an algorithm that is easy to understand and added 2 possibilites to enhance it - which you should do to see if you fully understood it.

    But feel free to test the code of CS001, too. I think the the if statement must be removed but some tests should show it. That algorithm might be harder to understand but that is also the algorithm I might have written if I had to. But I like this easy one, too. And a modern computer counting a few years, months and days? That is not really slow - as long as you do not have to do it over and over (e.g. a database with millions of rows and you want to provide queries calculating it ...)

    With kind regards,

    Konrad

    Edit: Changed the if statements to <= instead of <!
    Wednesday, January 11, 2012 3:23 PM
  • You can use Calendar.GetDaysInMonth.

    Or have the DateTime method handle it:

    DateTime date1 = new DateTime(2010, 8, 12);
    DateTime date2 = new DateTime(2011, 5, 3);
    
    int years=date2.Year-date1.Year;
    int months=date2.Month-date1.Month;
    
    if(date1.AddYears(years)>date2)
    {
        years--;
        months+=12;
    }
    
    if (date1.AddMonths(months) > date2) months--;
    
    date1 = date1.AddMonths(months).AddYears(years);
    int days = (date2 - date1).Days;
    
    Wednesday, January 11, 2012 4:27 PM

All replies

  • Hello Shaswat,

    try using this

                System.DateTime date1 = System.DateTime.Today;

                //e.g., System.DateTime date2 = new System.DateTime(Year, Month, Day);
                System.DateTime date2 = new System.DateTime(2000, 7, 18);

                int year = date1.Year - date2.Year;
                int month = date1.Month - date2.Month;
                int days = date1.Day - date2.Day;

                if (month < 0)
                    month = -(month);

                if (days < 0)
                    days = -(days);

                Console.WriteLine("Year: " + year + " Months:" + month + " Days:" + days);
                Console.ReadLine();     

    Cheers!


    Gore T.Richard
    Tuesday, January 10, 2012 1:24 PM
  • I think the code is not fully working or am I wrong?

    date1 could be 1st November (11) 2011
    date2 could be 20th December (12) 2010

    so you calculate:
    year = 2011-2010 = 1
    month = 11 - 12 = -1
    days = 1 - 20 = -19

    And then you only set month to 1 and days to 19.

    This is simply wrong in my eyes, because the difference is less than 1 year.

    And if days < 0, you have to know the number of days in the month of the 2nd date and add these! So your end result is a quite complex method. In this example, it was december with 31 days so it will be -19 + 31 = 12. And you have to reduce the number of months by one. (So month is -2 now!)

    So if month < 0 you have to:
    - Subtract 1 from years ==> 0
    - months = months + 12 ==> 10

    ==> 0 years, 10 months and 12 days.

    And this seems to be correct:
    20th December 2010 + 12 days is the 1th January 2011.
    and 11 months later it is the 1st November 2011.

    But that also shows, that the age given is simply not exact! 10 months 12 days is not a fixed number of days!

    So I would simply ask, if that information is of any value? Why is this information required?

    With kind regards,

    Konrad

    Edit: And that is the reason, that the build in functions are not providing this information! TimeSpan only gives you the days and not any months or years because that would not be a defined timespan any longer!
    Tuesday, January 10, 2012 1:41 PM
  • hi,

    Refer the below link.

    http://social.msdn.microsoft.com/Forums/en-US/csharplanguage/thread/ba4a98af-aab3-4c59-bdee-611334e502f2

     


    Don't forget to mark the post as answer or vote as helpful if it does, Regards - Rajasekhar.R
    Tuesday, January 10, 2012 2:09 PM
  • You can do as simple as this:

     

    Date1 = '01 Jan 2010'
    Date2 = '03 May 2011'

     

    var dif = Date2 - Date1; //It's a TimeSpan

    TimeSpan has all you need. Even more.
    Tuesday, January 10, 2012 3:05 PM
  • No it does not. The op wants to get the year and months. And that is not possible with TimeSpan.

    With kind regards,

    Konrad

    Tuesday, January 10, 2012 3:13 PM
  • TimeSpan has following properties. It does not have years and months

    http://msdn.microsoft.com/en-us/library/system.timespan.aspx

    Public property Supported by the XNA Framework Supported by Portable Class Library Days Gets the days component of the time interval represented by the current TimeSpan structure.
    Public property Supported by the XNA Framework Supported by Portable Class Library Hours Gets the hours component of the time interval represented by the current TimeSpan structure.
    Public property Supported by the XNA Framework Supported by Portable Class Library Milliseconds Gets the milliseconds component of the time interval represented by the current TimeSpan structure.
    Public property Supported by the XNA Framework Supported by Portable Class Library Minutes Gets the minutes component of the time interval represented by the current TimeSpan structure.
    Public property Supported by the XNA Framework Supported by Portable Class Library Seconds Gets the seconds component of the time interval represented by the current TimeSpan structure.
    Public property Supported by the XNA Framework Supported by Portable Class Library Ticks Gets the number of ticks that represent the value of the current TimeSpan structure.
    Public property Supported by the XNA Framework Supported by Portable Class Library TotalDays Gets the value of the current TimeSpan structure expressed in whole and fractional days.
    Public property Supported by the XNA Framework Supported by Portable Class Library TotalHours Gets the value of the current TimeSpan structure expressed in whole and fractional hours.
    Public property Supported by the XNA Framework Supported by Portable Class Library TotalMilliseconds Gets the value of the current TimeSpan structure expressed in whole and fractional milliseconds.
    Public property Supported by the XNA Framework Supported by Portable Class Library TotalMinutes Gets the value of the current TimeSpan structure expressed in whole and fractional minutes.
    Public property Supported by the XNA Framework Supported by Portable Class Library TotalSeconds Gets the value of the current TimeSpan structure expressed in whole and fractional seconds.

    Shashwat Tripathi India
    Tuesday, January 10, 2012 5:50 PM
  • TimeSpan wouldn't have month or year fields, because the length of a month or year is variable.

    Does this logic/pseudo code work?
    Year: Date2.Year - Date1.Year;
    Month: Date2.Month - Date1.Month;
    Days: Date2.Day - Date1.Day;

    Tuesday, January 10, 2012 8:01 PM
  • In answer to my own question, that logic doesn't work (as pointed out by previous posts). I doubt the logic you are looking for is built into the system libraries.

    Tuesday, January 10, 2012 8:40 PM
  •             DateTime date1 = new DateTime(2010, 8, 12);
                DateTime date2 = new DateTime(2011, 5, 3);
    
                int days = 0;
                int months = 0;
                int years = 0;
    
                years = date2.Year - date1.Year;
                months = date2.Month - date1.Month;
                days = date2.Day - date1.Day;
    
                if (days < 0)
                {
                    months--;
                    int month = date2.Month - 1;
                    if (month == 0)
                    {
                        month = 12;
                    }
                    days += GetDaysInMonth(month, date2.Year);
                }
    
                if (months < 0)
                {
                    years--;
                    months += 12;
                }
    
                MessageBox.Show(this, "Years = " + years.ToString() + "; Months = " + months.ToString() + "; Days = " + days.ToString(), "Result", MessageBoxButtons.OK, MessageBoxIcon.Information);
    
            private int GetDaysInMonth(int month, int year)
            {
                int ret = 31;
    
                switch (month)
                {
                    case 2:
                        ret = 28;
                        // leap year calculation.
                        if ((year % 4) == 0)
                        {
                            if ((year % 400) != 0)
                            {
                                ret++;
                            }
                        }
                        break;
                    case 4:
                    case 6:
                    case 9:
                    case 11:
                        ret = 30;
                        break;
                          
                }
    
                return ret;
            }


    The calculation is made difficult by the fact that the number of days in a month is variable depending both on month and year.  The year factors in when calculating February as either 28 or 29 days.  I have tried this, and I have not tried it in all cases, but maybe it can get you started.

    There is no existing method in .NET which gives you this result, and the calculation isn't a one-liner.

    Tuesday, January 10, 2012 10:47 PM
  • Yeah, that is the algorithm I tried to describe. But I am wondering: if (month==0) { month=12; }: Why did you add that code? I think this part should be removed.

    With kind regards,

    Konrad

    Wednesday, January 11, 2012 7:00 AM
  • Yeah, that is the algorithm I tried to describe. But I am wondering: if (month==0) { month=12; }: Why did you add that code? I think this part should be removed.

    With kind regards,

    Konrad

    Hi, Neitzel..

    I think you can do it.. why don't you give me an effective and accurate algorithm please..??


    Shashwat Tripathi India
    Wednesday, January 11, 2012 1:59 PM
  • Hi Shashwat,

    in my eyes it is always important to fully understand the code so I found a quite nice algorithm for you, which is not very effective but it works fine:

            public static void DateDiff(DateTime from, DateTime to, out int years, out int months, out int days)
            {
                // validate dates
                if (from > to)
                    throw new InvalidOperationException();

                // initialize
                years = 0;
                months = 0;
                days = 0;

                // We need a temporary date
                DateTime temp = from;

                // get years
                while (temp.AddYears(1) <= to)
                {
                    temp = temp.AddYears(1);
                    years++;
                }

                // get months
                while (temp.AddMonths(1) <= to)
                {
                    temp = temp.AddMonths(1);
                    months++;
                }

                // get days
                while (temp.AddDays(1) <= to)
                {
                    temp = temp.AddDays(1);
                    days++;
                }
            }
    It is just a "small child" algorithm. Instead of calculating anything, we simply count the years, months and days :)

    Easy to understand I hope. But the hard point to understand: This is no longer the calculation of a real timespan! It is the age of something which has a birthdate! 1 year can be 365 or 366 days. 1 month can mean 27, 28, 30 or 31 days! It is no longer exact!

    And of course we can optimize the code:
    1st) If oyu have multiple years, it might be better to get to-from in days and divide it by 366. That is the minimum of years. Just set years to that and add these years to "from". That way you do not have to count to many years.

    2nd) The days at the end must not be counted. You can simply do (to - temp).Days to get the days.

    So I provided an algorithm that is easy to understand and added 2 possibilites to enhance it - which you should do to see if you fully understood it.

    But feel free to test the code of CS001, too. I think the the if statement must be removed but some tests should show it. That algorithm might be harder to understand but that is also the algorithm I might have written if I had to. But I like this easy one, too. And a modern computer counting a few years, months and days? That is not really slow - as long as you do not have to do it over and over (e.g. a database with millions of rows and you want to provide queries calculating it ...)

    With kind regards,

    Konrad

    Edit: Changed the if statements to <= instead of <!
    Wednesday, January 11, 2012 3:23 PM
  • You can use Calendar.GetDaysInMonth.

    Or have the DateTime method handle it:

    DateTime date1 = new DateTime(2010, 8, 12);
    DateTime date2 = new DateTime(2011, 5, 3);
    
    int years=date2.Year-date1.Year;
    int months=date2.Month-date1.Month;
    
    if(date1.AddYears(years)>date2)
    {
        years--;
        months+=12;
    }
    
    if (date1.AddMonths(months) > date2) months--;
    
    date1 = date1.AddMonths(months).AddYears(years);
    int days = (date2 - date1).Days;
    
    Wednesday, January 11, 2012 4:27 PM