# Convert number of days to days/ months/ years RSS

## 15 replies

Last post Jan 26, 2011 08:33 AM by donpisci

Member

74 Points

178 Posts

### Convert number of days to days/ months/ years

Hi All,

I'm currently building a webservice and my client has asked me to return the time remaining until a particular date. I'm able to calculate the number of days remaining, but ideally instead of having 473 days for example, I would be able to show something  like '1 year 4 months and 12 days'

Any ideas?

All-Star

56620 Points

8958 Posts

### Re: Convert number of days to days/ months/ years

Hey,

You can use DateTime.AddDays() to add the number of days on to today (DateTime.Now).

```int NumberOfDays = 473;

Its not built into .net but Scott Mitchell covers how to make a relative date string such as your example in this article:

All-Star

41188 Points

6034 Posts

### Re: Convert number of days to days/ months/ years

If you subtract two dates, that will return an instance of TimeSpan, which will represent the difference between the two dates. Like this..

```DateTime oldDate = new DateTime(2007, 8, 15);
DateTime newDate = DateTime.Now;
TimeSpan ts = newDate - oldDate;

Console.WriteLine("years: {0} ", ts.Days);
Console.WriteLine("hours: {0} ", ts.Hours);
Console.WriteLine("Minutes: {0} ", ts.Minutes);```

Getting in years and days is more complex, because of leapyears.

Vijay Kodali || My Blog

"Don't be afraid to be wrong; otherwise you'll never be right."

Contributor

4181 Points

1041 Posts

### Re: Convert number of days to days/ months/ years

DateTime StartDate = Convert.ToDateTime("01/1/2010");
DateTime EndDate = Convert.ToDateTime("04/3/2011");
string strResult = CalculateDays(StartDate, EndDate);

public string CalculateDays(DateTime StartDate, DateTime EndDate)
{
DateTime oldDate;

DateTime.TryParse(StartDate.ToShortDateString(), out oldDate);
DateTime currentDate = EndDate;

TimeSpan difference = currentDate.Subtract(oldDate);

// This is to convert the timespan to datetime object
DateTime DateTimeDifferene = DateTime.MinValue + difference;

// Min value is 01/01/0001
// subtract our addition or 1 on all components to get the
//actual date.

int InYears = DateTimeDifferene.Year - 1;
int InMonths = DateTimeDifferene.Month - 1;
int InDays = DateTimeDifferene.Day - 1;

return InYears.ToString() +" Years "+ InMonths.ToString() +" Months " + InDays.ToString() +" Days";
}

Thanks,
Raj Sedhain
• ### SGWellens

All-Star

126033 Points

10311 Posts

Moderator

### Re: Convert number of days to days/ months/ years

#### rajsedhain

DateTime oldDate;

DateTime.TryParse(StartDate.ToShortDateString(), out oldDate);

In your example, the above line does nothing (it converts a datetime to a string and then back to a datetime).  If you were trying to strip the time component from a DateTime this is the way to do it:

oldDate = StartDate.Date;

Steve Wellens

My blog

Star

13591 Points

2571 Posts

### Re: Convert number of days to days/ months/ years

You could add the days to a known base date and then extract the components and subtract the base.  Like this

```var baseDate = new DateTime(1,1,1);
Console.Write("{0} years, {1} months and {2} days",
end.Year - baseDate.Year,
end.Month - baseDate.Month,
end.Day - baseDate.Day);```

You will get different results depending on which base year you use because of leap years (as noted above).  For example,  if you have 59 days and a base of 1/1/1 you get 2 months and 0 days, for a base date of 1/1/2000 you get 1 months and 28 days.  Take your pick.

Got a c# problem? Try .NET Book Zero from Charles Petzold, it's a free pdf.

Member

152 Points

60 Posts

### Re: Convert number of days to days/ months/ years

Here you go:

```int numberOfDays = 473;
DateTime date = new DateTime(new TimeSpan(numberOfDays, 0, 0, 0).Ticks);
string dateUntil = string.Format("{0} year(s), {1} month(s) and {2} day(s)", date.Year-1, date.Month-1, date.Day-1);```

The -1 for the year, month and day in the string.Format is needed because, well, we start in the year 1 month 1 and day 1 so if numberOfDays = 1 we are in year 1, month 1 and day 2.

Good luck!

And mark the post answered if this works for you ;)

• Edited by bmhc on Jan 22, 2011 12:20 PM

Member

403 Points

114 Posts

### Re: Convert number of days to days/ months/ years

You can use this code also

DateTime StartDate = DateTime.Now;
DateTime EndDate = Convert.ToDateTime("12/31/2015");

string timeStr = "";
int yr = 0;
int mth = 0;
int days = 0;

TimeSpan ts = new TimeSpan();
ts = EndDate.Subtract(StartDate);
yr = (ts.Days / 365);

do
{
for (int i = 0; i <= 12; i++)
{
{
mth = i;
}
else
{
break;
}
}

if (mth > 12)
yr = yr + 1;
} while (mth > 12);

if (yr == 1)
timeStr += yr.ToString() + " year ";
else if (yr > 0)
timeStr += yr.ToString() + " years ";

if (mth == 1)
timeStr += mth.ToString() + " month ";
else if (mth > 0)
timeStr += mth.ToString() + " months ";

if (days == 1)
timeStr += days.ToString() + " day ";
else if (days > 0)
timeStr += days.ToString() + " days";

Label1.Text=  timeStr;

"Mark As Answer" if it helps .

• ### mbanavige

All-Star

135173 Points

15506 Posts

ASPInsiders

Moderator

MVP

### Re: Convert number of days to days/ months/ years

Using the timespan has limitations as it doesnt do months and years.  Even the Scott Mitchell acticle stops with Days as it used a timespan.

Paul's method was nice and concise and looked promising. But as he noted, the issue of leap years still exists.  I also found some additional dates unrelated to leapyears that resulted in an incorrect result when using that base date method. for example, checking 4/30/2011 to 6/30/2011 resulted in 2 months, 2 days when it should be just 2 months. Note that my test for validity is that after determining the days/months/years difference between a startdate and enddate, i should be able to add the years/months/days back to the startdate and arrive back at the original enddate.

The method from bmhc is fundamentally no different that Paul's.

The method from vaibhav_shah1988 fared a bit better in results, but it also return invalids results for some cases. for example, checking 1/1/2010 to 12/31/2012 resulted in 3 years when it should be just 2 years 11 months 30 days.  There seems to be an edge case bug in that code where going from the first day of a year to the last day of a year lands you on a Days value of -1.

Rather than getting too complex and looping through the dates to get a final result, we could go in a completely different direction and just treat this as a basic math subtraction problem.

Instead of our numbers having 100's 10's and 1's columns, we have year's month's and day's columns

endYear   endMonth   endDay
- startYear startMonth startDay
------------------------------------
=     years     months     days

And when subtracting, we subtract the columns from right to left and we borrow numbers from the left as needed to keep each columns result from going negative.  Borrowing from years to months is easy as years always have 12 months.  Borrowing from months to days is a little trickier as not all months have the same number of days and there's the issue of that pesky little leapyear month.  But it turns out to be a relatively easy thing to do anyways.

So here's a twist on a time span class that does the math on the dates.

```public class TimeSpan2
{

private int _years;
private int _months;
private int _days;

public int Years
{
get { return _years; }
}
public int Months
{
get { return _months; }
}
public int Days
{
get { return _days; }
}

public TimeSpan2(DateTime startDate, DateTime endDate)
{
//for simplicity, let's keep the TimeSpan2 to positive time spans
if (startDate > endDate)
{
DateTime tmpSwap = startDate;
startDate = endDate;
endDate = tmpSwap;
}

int startYear = startDate.Year;
int startMonth = startDate.Month;
int startDay = startDate.Day;

int endYear = endDate.Year;
int endMonth = endDate.Month;
int endDay = endDate.Day;

//perform the date math by subtracting startdate from enddate
//we actually subtract using the individual y/m/d pieces
//borrowing from the left as needed to avoid going negative...

// working on the 1's / day's column
if (endDay < startDay)
{
//borrow days from months column
//use previous month so we can see exactly how many days it actually has
endDay += DateTime.DaysInMonth(previousMonth.Year, previousMonth.Month);

//decrement our endmonth number since we just borrowed a month
endMonth -= 1;

//watch for invalid month and borrow from the years column if needed
if (endMonth < 1)
{
endMonth += 12;
endYear -= 1;
}
}

// working on the 10's / month's column
if (endMonth < startMonth)
{
//borrow months from the years column
endMonth += 12;
endYear -= 1;
}

_years = endYear - startYear;
_months = endMonth - startMonth;
_days = endDay - startDay;

}

public override string ToString()
{
//build up date parts and pluralize as needed
const string plural = "s";

//years and months not shown if they are zero but days are.
string yearString = (Years == 0 ? string.Empty : string.Format("{0} year{1}, ", Years, (Years > 1 ? plural : string.Empty))).ToString();
string monthString = (Months == 0 ? string.Empty : string.Format("{0} month{1} and ", Months, (Months > 1 ? plural : string.Empty))).ToString();
string dayString = string.Format("{0} day{1}", Days, (Days != 1 ? plural : string.Empty));
return string.Format("{0}{1}{2}", yearString, monthString, dayString);
}
}```

using the class is as simple as:

```DateTime startdate = new DateTime(2011, 1, 22);
DateTime enddate = new DateTime(2012, 5, 17);

Debug.WriteLine(new TimeSpan2(startdate, enddate));
```

I ran a number of tests to insure that the errors noted in the other techniques were not present and that it could cross over leap years without issue.  Here are the test results contrasting the math based technique with the base date technique.

Notice that sometimes that Basedate algorithm gave a slightly different result that the TimeSpan2, but i colored it green (it was ok) if adding it back to the startdate landed you on the original enddate.  The pink boxes indicate where adding the years,months,days back to the startdate resulted in a different enddate.

 Test Case TimeSpan2 Algorithm Basedate Algorithm Check short month to long month: 2/1/2011 to 3/1/2011 1 month and 0 days 0 years, 0 months and 28 days Check short month to long month: 2/15/2011 to 3/15/2011 1 month and 0 days 0 years, 0 months and 28 days Check long month to short month: 1/1/2011 to 2/1/2011 1 month and 0 days 0 years, 1 months and 0 days Check long month to short month: 1/31/2011 to 2/28/2011 28 days 0 years, 0 months and 28 days Check long month to long month: 1/1/2011 to 3/1/2011 2 months and 0 days 0 years, 2 months and 0 days Check long month to long month: 1/31/2011 to 3/31/2011 2 months and 0 days 0 years, 2 months and 0 days Check short month to short month: 2/1/2011 to 4/1/2011 2 months and 0 days 0 years, 2 months and 0 days Check short month to short month: 4/30/2011 to 6/30/2011 2 months and 0 days 0 years, 2 months and 2 days - Invalid Check short month to short month: 2/28/2011 to 4/30/2011 2 months and 2 days 0 years, 2 months and 2 days Check short month to long month: 4/30/2011 to 5/30/2011 1 month and 0 days 0 years, 0 months and 30 days Check short month to long month: 4/30/2011 to 5/31/2011 1 month and 1 day 0 years, 1 months and 0 days - Invalid Check leapyear: 2/28/2012 to 3/1/2012 2 days 0 years, 0 months and 2 days Check leapyear: 2/28/2012 to 3/31/2012 1 month and 3 days 0 years, 1 months and 1 days - Invalid Check leapyear: 2/1/2012 to 3/1/2012 1 month and 0 days 0 years, 0 months and 29 days Check crossing year end: 12/31/2011 to 1/1/2012 1 day 0 years, 0 months and 1 days Check forum post example: 1/22/2011 to 5/9/2012 1 year, 3 months and 17 days 1 years, 3 months and 18 days - Invalid

I always enjoy a good puzzle... [:)]

Mike Banavige

Star

13591 Points

2571 Posts