## 10 replies

Last post Oct 07, 2009 03:08 PM by Mechanic

Participant

751 Points

579 Posts

### TimeSpan and years

Hi,

What is easiest way to get difference between two dates in years, months, days, hours, minutes and seconds, taking into account month length and leap years?

TimeSpan has Days and smaller properties but does not have Years and Months.

__

Member

360 Points

347 Posts

### Re: TimeSpan and years

I got interested by this and I ran some tests.

Let me ask you a question. What is normal:

30 January - 28 Feb = 29 days right.

How About  30 January - 1 Mar = 1 month 2 days or 30 days?

Because if it's 1 month 2 days, then this is the code that computes it:

```DateTime date1 = dateTimePicker1.Value;
DateTime date2 = dateTimePicker2.Value;

int oldMonth = date2.Month;
while (oldMonth == date2.Month)
{
}

int years = 0, months = 0, days = 0, hours = 0, minutes = 0, seconds = 0, milliseconds = 0;

// getting number of years
while (date2.CompareTo(date1) >= 0)
{
years++;
}
years--;

// getting number of months and days
oldMonth = date2.Month;
while (date2.CompareTo(date1) >= 0)
{
days++;
if ((date2.CompareTo(date1) >= 0) && (oldMonth != date2.Month))
{
months++;
days = 0;
oldMonth = date2.Month;
}
}
days--;

TimeSpan difference = date2.Subtract(date1);

txtDateDifference.Text =
"Difference: " +
years.ToString() + " years" +
", " + months.ToString() + " months" +
", " + days.ToString() + " days" +
", " + difference.Hours.ToString() + " hours" +
", " + difference.Minutes.ToString() + " minutes" +
", " + difference.Seconds.ToString() + " seconds" +
", " + difference.Milliseconds.ToString() + " milliseconds";```

I enjoy it every minute of my life

Member

4 Points

43 Posts

### Re: TimeSpan and years

Wow! That's a lot of code, which is of course what I wanted to avoid if possible. But you had some questions (in Italics below) at the top of your reply. Let me answer them first in bold print below.

Let me ask you a question. What is normal:

30 January - 28 Feb = 29 days right.

I would call that 1 month + 2 day unless it is a leap year. In a leap year, it would be 30 days (january has 31 days).

How About  30 January - 1 Mar = 1 month 2 days or 30 days?

I see that as 1 month plus 3 days, always. Since the entire month of febuary is included in the time frame, we have 1 month (Feb 1-29 or Feb 1 - 28) plus Jan 30, Jan 31 and Mar 1 or 3 days.

I noticed that my number of days is one larger than yours. Either I am introducing an off by one error, or you are counting only 30 days for January, which has 31 days. It is not important to figure out who is wrong, I just wanted to point out the difference and what is so complicated about this seemingly simply conversion.

I will copy your code to my system and run it thru some tests, but I assume you did not consider leap years in your calculation. Is that correct? I am not sure if that can even be done, or if it matters in the long run, since the leap day is added every 4 years to make up for partial day we don't count in the 3 years before the leap year. (A years is actually 365.24 or 365.25 days long. I don't recall the actual number right now.)

Thank you for working out the code for me. I was really hoping for something less complicated, but if nobody else comes up with a simpler solution, I will use your code.

So for now my question is still unanswered: Does anyone know of a reliable C# method that can do the conversion for me?

URW

uwillmore

Member

4 Points

43 Posts

### Re: TimeSpan and years

I just realized that I replied to the wrong post. I clicked the wrong like somewhere and ended up replying to this post, rather than replying to my own threat which has a similar topic and subject.  I apologize and hope I did not cause too much confusion.

URW

uwillmore

Member

4 Points

43 Posts

### Re: TimeSpan and years

I asked a very similar question a few minutes ago and just got the anwser I needed. Since I posted to this threat accidentaly earlier, I figured I'll make up for my mistake by sharing the answer. My question was only concerned with years and months, but TimeSpan contains properties for days, minutes and smaller as you know. ANyway, here is the answer I got:

protected void Button1_Click(object sender, EventArgs e)
{
DateTime Birth = new DateTime(1954, 7, 30);
DateTime Today = DateTime.Now;

TimeSpan Span = Today - Birth;

DateTime Age = DateTime.MinValue + Span;

// note: MinValue is 1/1/1 so we have to subtract...
int Years = Age.Year - 1;
int Months = Age.Month - 1;
int Days = Age.Day - 1;
Response.Write(Years.ToString() + " Years, " + Months.ToString() + " Months, " + Days.ToString() + " Days<br />");
}

I have not tried it yet, but I would be surprised if it did not work as advertised. SGWellens gave me this solution and I hope it will work for you too.

URW

uwillmore

None

0 Points

2 Posts

or

None

0 Points

1 Post

### Re: TimeSpan and years

Here's what I did. It seems to work, though I'm not sure if the performance is all that great. [UPDATED] Well, I can't get my code listing to display properly in the forum because it doesn't like the less-than sign. Sorry! Private Function GetAgeString(ByVal dateStart As DateTime, ByVal dateEnd As DateTime) As String Dim years, months, days As Integer Dim calcDate As DateTime = dateStart 'Get years While calcDate < dateEnd If calcDate.AddYears(1) <= dateEnd Then years += 1 calcDate = calcDate.AddYears(1) Else Exit While End If End While 'Get months While calcDate <= dateEnd If calcDate.AddMonths(1) <= dateEnd Then months += 1 calcDate = calcDate.AddMonths(1) Else Exit While End If End While 'Get days Dim daysAge As TimeSpan = dateEnd.Subtract(calcDate) days = daysAge.Days Return String.Format("{0}y {1}m {2}d", years, months, days) End Function

None

0 Points

3 Posts

### Re: TimeSpan and years

I tired the suggested solution and the created this solution based on the first suggeston.

Here is a test that proves its accuracy.

http://michaelkappel.com/Dates.aspx

Basing this kind of date diffrence on DateTime.MinValue is very inaccurate because it does not account for leap years or number of days in a month. April 19th will not end up 3 months away July 19th using DateTime.MinValue you will end up with incorrect days.

Thanks

Michael Kappel

None

0 Points

1 Post

### Re: TimeSpan and years

Oct 07, 2009 12:12 AM|Ross Presser|LINK

Great work, Michael. The only thing more tha I could ask is an equivalent to the  TimeSpan.TryParse() method, so I can use it to represent long spans of time without having to work from a date. (Actually, so I can pass a program something like "2y3m5d8h ago" and come up with the time that matches that.)

None

0 Points

3 Posts

### Re: TimeSpan and years

That is a great idea!

None

0 Points

3 Posts

### Re: TimeSpan and years

I added a factory method with a few overloads to create DateDifferentials based on input parameters. It would not be to hard to use a regex to parse out the values from a string. Unless I am missing somthing the CreateDifferential method does not need to do anything difficault. THis is basicly all I added.

http://www.mikekappel.com/examples/CS/Model/DateDifferential.htm

DateTime tempLaterDate = startingDate;
DateTime tempEarlierDate = startingDate;
if (differentialType == DateDifferentialType.Ascending)
{

return new DateDifferential(tempLaterDate, tempEarlierDate, calculateMillennia, calculateCenturies, calculateDecades, calculateYears, calculateMonths, calculateWeeks,calculateDays, detail);
}
if (differentialType == DateDifferentialType.Descending)
{