e.g. 70,105 - calculate any date of birth that meets the age range of the parameters
CalculateDob(int youngestAge, int oldestAge)
{
Random r = new Random();
int age = 0;
age = r.Next(70, 105);
var year = DateTime.Now.Year - age;
var month = r.Next(1, 12);
var day = r.Next(1, 28);
return new DateTime(year, month, day);
}
My current soluton almost works, but fails in some edge cases i.e. returns 69 in some circumstances due what i presume a month issue.
Any suggestions?
Reason you are getting 69 years of age sometimes is because if CalculateDob returns month which is after current month (DateTime.Now); then Dob still wouldn't reach 70 years. Also, you should bring random constructor out from the method, and make it static so that you don't keep seeding rand generator during every call.
public static void Main(string[] args)
{
for (int i = 0; i < 100; i++)
{
var birthDate = CalculateDob(70, 105);
var now = DateTime.Now;
int age = now.Year - birthDate.Year;
if (now.Month < birthDate.Month || (now.Month == birthDate.Month && now.Day < birthDate.Day))
{
age--;
}
Console.WriteLine(age);
}
}
//Construct this as static so that we don't keep seeding the rand
private static readonly Random _random = new Random();
static DateTime CalculateDob(int youngestAge, int oldestAge)
{
int age = 0;
age = _random.Next(70, 105);
var today = DateTime.Now;
var year = today.Year - age;
var month = _random.Next(1, 12);
//Age might less than youngest age,
//if born at/after current month, edge condition
if (month >= today.Month)
{
month = today.Month - 1;
if (month < 1)
{
year--;
month = 12;
}
}
var day = _random.Next(1, DateTime.DaysInMonth(year, month));
return new DateTime(year, month, day);
}
Related
using System;
using System.Text.RegularExpressions;
namespace calendar
{
class Program
{
static void Main()
{
int year;
int day;
string[] month = new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" };
int[] days = new int[] { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
Console.Write("Enter the year for which you wish to generate the calendar >> ");
int.TryParse(Console.ReadLine(), out year); // Validate //
Console.Write("Enter the day of the week that January first is on >> ");
int.TryParse(Console.ReadLine(), out day); // Validate //
while (day > 31 || day < 1) // Reprompt for value if date is out of range //
{
Console.WriteLine("Enter a valid date >> ");
Console.Write("Enter the day of the week that January first is on >> ");
int.TryParse(Console.ReadLine(), out day); // Validate //
}
switch (LeapYear(year)) // Switch statement checks if Leap Year is true //
{
case true:
days[1] += 1;
Console.WriteLine("Calendar for year - {0}", year);
for (int i = 0; i < month.Length; i++)
{
Console.WriteLine("\n" + month[i]);
day = DisplayCalender(days[i], day);
Console.Write("\n");
}
break;
}
}
public static int DisplayCalender(int days, int start) //Display Function//
{
int startDay = start;
Console.WriteLine("Sun\tMon\tTue\tWed\tThu\tFri\tSat");
for (int i = 0; i < start; i++)
Console.Write("\t");
for (int i = 1; i <= days; i++)
{
if (startDay > 6)
{
startDay = 0;
Console.WriteLine();
}
Console.Write(i + "\t");
startDay++;
}
return startDay;
}
public static Boolean LeapYear(int year)
{
if ((year % 400 == 0) || ((year % 4 == 0) && !(year % 100 == 0))) // Checks each OR AND statements and return true or false //
{
return true;
}
else
return false;
}
}
}
I'm imagining the problem you're describing is having a month that starts on Sunday is making the calendar skip an entire line. Like the image:
That is happening because your method public static int DisplayCalender(int days, int start) is receiving the parameter int start with a value of 7.
That makes write tabs on the whole week on your first for and then skip the line on the second for.
To solve the issue you can simply reassign startDay with zero when it is 7 and check on you tab loop for startDay instead of start:
public static int DisplayCalender(int days, int start) //Display Function//
{
int startDay = start == 7 ? 0 : start;
Console.WriteLine("Sun\tMon\tTue\tWed\tThu\tFri\tSat");
for (int i = 0; i < startDay; i++)
Console.Write("\t");
for (int i = 1; i <= days; i++)
{
if (startDay > 6)
{
startDay = 0;
Console.WriteLine();
}
Console.Write(i + "\t");
startDay++;
}
return startDay;
}
This will give you the expected result:
What can you improve from here?
Making all that from scratch probably made you learn a lot about loop and flow. If you have some time check on DateTime.
There you have methods to find leap years, day of the week, and Month. That would help you simplify your code a lot.
Welcome to StackOverflow!
First I must say you are overcomplicating this very much, there is a perfect date library out of the box that you could have used.
For example:
DateTime now = DateTime.Now;
bool isLeapYear = DateTime.IsLeapYear(now.Year);
int daysInCurrentMonth = DateTime.DaysInMonth(now.Year, now.Month);
Instead of this:
Console.WriteLine("Sun\tMon\tTue\tWed\tThu\tFri\tSat");
for (int i = 0; i < start; i++)
Console.Write("\t");
Do this:
Console.WriteLine("Sun\tMon\tTue\tWed\tThu\tFri\tSat");
if (start < 7)
{
for (int i = 0; i < start; i++)
{
Console.Write("\t");
}
}
And instead of this:
if (startDay > 6)
{
startDay = 0;
Console.WriteLine();
}
do this:
if (startDay > 6)
{
startDay = 0;
if (i!=1)
{
Console.WriteLine();
}
}
So DisplayCalender method should look like this:
public static int DisplayCalender(int days, int start) //Display Function//
{
int startDay = start;
Console.WriteLine("Sun\tMon\tTue\tWed\tThu\tFri\tSat");
if (start < 7)
{
for (int i = 0; i < start; i++)
{
Console.Write("\t");
}
}
for (int i = 1; i <= days; i++)
{
if (startDay > 6)
{
startDay = 0;
if (i != 1 )
{
Console.WriteLine();
}
}
Console.Write(i + "\t");
startDay++;
}
return startDay;
}
Instead of specifying
"string[] week_Days = {"Monday", "Tuesday"...};"
How to dynamically set days as array?
I tried solving it, but couldn't get starting day as "Sunday" -
DateTime days = DateTime.Now;
string[] weekDays = new string[7];
for (int i = 0; i < weekDays.Length; i++)
{
weekDays[i] = string.Format("{0:dddd}", days.AddDays(i));
Console.WriteLine(weekDays[i]);
days = DateTime.Now;
}
Output -
Wednesday
Thursday
Friday
Saturday
Sunday
Monday
Tuesday
using System;
using System.Globalization;
static void Main()
{
string[] weekDays = new CultureInfo("en-us").DateTimeFormat.DayNames;
for (int i = 1; i <= 7; i++)
Console.WriteLine(weekDays[i % 7]);
}
You could use the DayOfWeek enum:
string[] weekdays = Enum.GetNames(typeof(DayOfWeek));
EDIT: If you need to change the start day of the week:
private static string[] GetWeekdays(DayOfWeek firstDayOfWeek)
{
string[] weekdays = new string[7];
DateTime dateTime = DateTime.Now;
while (dateTime.DayOfWeek != firstDayOfWeek)
{
// Find the next date with start day of week
dateTime = dateTime.AddDays(1);
}
for (int i = 0; i < 7; i++)
{
// Get day of week of current day, add 1 day, iterate 7 times.
weekdays[i] = dateTime.DayOfWeek.ToString();
dateTime = dateTime.AddDays(1);
}
return weekdays;
}
You can use this LINQ query. The only challenge is to get the correct order:
DayOfWeek firstWeekDay = DateTimeFormatInfo.CurrentInfo.FirstDayOfWeek;
string[] weekDays = Enum.GetValues(typeof(DayOfWeek)).Cast<DayOfWeek>()
.OrderBy(dow => dow < firstWeekDay ? 7-(int)dow : dow-firstWeekDay)
.Select(dow => dow.ToString())
.ToArray();
Maybe someone has a more elegant way than this OrderBy.
string[] week_Days = new string[7];
DayOfWeek day = DayOfWeek.Sunday;
for (int i = 0; i < week_Days.Length; i++)
{
week_Days[i] = day.ToString();
Console.WriteLine(week_Days[i]);
day++;
}
Instead of assigning DateTime property, Use DayOfWeek. it solves the issue with ease.
Your code fails because DateTime.Now isn't always on a sunday:
DateTime days = DateTime.Now;
Better use the existing DayOfWeek enum:
string[] weekdays = Enum.GetNames(typeof(DayOfWeek));
This could be done in this way too. Until you get "Monday", add days to the DateTime.Now.
int j = 0;
string[] weekDays = new string[7];
DateTime days = DateTime.Now;
while (weekDays[0] != "Sunday")
{
days = days.AddDays(j++);
weekDays[0] = string.Format("{0:dddd}", days);
if (weekDays[0] != "Sunday")
days = DateTime.Now;
}
for (int i = 0; i < weekDays.Length; i++)
{
weekDays[i] = string.Format("{0:dddd}", days.AddDays(i));
Console.WriteLine(weekDays[i]);
}
My program is currently working to get the next day except I seem to have an array to which I want removing. Whenever I remove the array within my Day property then my month is having an issue. Any ideas for a solution towards this issue. Please do not mention me not wanting to use DateTime or whatever, as I am doing this, as a challenge for myself. Basically the issue is when I remove my array I am having a problem or issue with the month and this array is useless, as I have if statements within my nextDay method.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace date
{
class Program
{
static void Main(string[] args)
{
string british, american; // sets two strings one for british and other for american
Console.Title = "NextDate Application";
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("\t\t\t\t\t\tNextDate Application\n\t\t\t\t\t-------------------------------------"); // title
Console.ResetColor();
Console.WriteLine("This application will allow you to enter a valid date and this will get the next day."); // intro of what the application does
Console.WriteLine("The application takes leap years into account\n"); // intro of what the application does
Console.WriteLine("enter key 'b' for British Format or 'a' for American Format"); // writes the line
char key = Console.ReadKey().KeyChar;
if (key == 'b') // if key b is entered
{
british = GetValidInput("\nplease enter date as dd/MM/yyyy\n"); // tells user to input a date in the format
int day; // sets variable
int month; // sets variable
int year; // sets variable
Date date; // instance of class Date
string[] read = british.Split('/'); // "/" can be read from each value and sets new array
day = int.Parse(read[0]); // day is first position in array
month = int.Parse(read[1]); // month is second position in array
year = int.Parse(read[2]); // year is third position in array
try
{
date = new Date(day, month, year); // initialises a new date class
for (int i = 0; i < 1; i++)
{
date.nextDay(); // calls nextDay method
Console.WriteLine("{0}/{1}/{2}", date.Day, date.Month, date.Year); // writes the line in a format of d/m/y
Console.ReadLine(); // reads the line
}
}
catch (ArgumentOutOfRangeException exc)
{
Console.WriteLine(exc.Message); // states the message for ArgumentOutOfRangeException
Console.Read(); // breaks
}
}
else if (key == 'a')
{
american = GetValidInput("\nplease enter date as MM/dd/yyyy\n"); // tells user to input a date in the format
int day; // sets variable
int month; // sets variable
int year; // sets variable
Date date; // instance of class Date
string[] read = american.Split('/'); // "/" can be read from each value and sets new array
month = int.Parse(read[0]); // month is first position in array
day = int.Parse(read[1]); // day is second position in array
year = int.Parse(read[2]); // year is third position in array
try
{
date = new Date(day, month, year); // initialises a new date class
for (int i = 0; i < 1; i++)
{
date.nextDay(); // calls nextDay method
Console.WriteLine("{0}/{1}/{2}", date.Month, date.Day, date.Year); // writes the line in a format of m/d/y
Console.ReadLine(); // reads the line
}
}
catch (ArgumentOutOfRangeException exc)
{
Console.WriteLine(exc.Message); // states the message for ArgumentOutOfRangeException
Console.Read(); // breaks
}
}
}
static string GetValidInput(string prompt)
{
while (true)
{
string input;
Console.WriteLine(prompt);
input = Console.ReadLine();
if (!string.IsNullOrEmpty(input))
{
return input;
}
Console.WriteLine("error no input");
}
}
class Date
{
private int _month; // 1-12
private int _day; // 1-31 depending on month
private int _year; // sets the year
public Date(int day, int month, int year)
{
Month = month;
Day = day;
Year = year;
}
public void nextDay() // nextDay method
{
{
if (_day == 31 && _month == 1) // jan
{
_day = 1;
_day = _day - 1;
_month = 2;
}
if (_day == 28 && _month == 2) // feb
{
_day = 1;
_day = _day - 1;
_month = 3;
}
if (_day == 31 && _month == 3) // march
{
_day = 1;
_day = _day - 1;
_month = 4;
}
if (_day == 30 && _month == 4) // april
{
_day = 1;
_day = _day - 1;
_month = 5;
}
if (_day == 31 && _month == 5) // May
{
_day = 1;
_day = _day - 1;
_month = 6;
}
if (_day == 30 && _month == 6) // June
{
_day = 1;
_day = _day - 1;
_month = 7;
}
if (_day == 31 && _month == 7) // July
{
_day = 1;
_day = _day - 1;
_month = 8;
}
if (_day == 31 && _month == 8) // Aug
{
_day = 1;
_day = _day - 1;
_month = 9;
}
if (_day == 30 && _month == 9) // Sept
{
_day = 1;
_day = _day - 1;
_month = 10;
}
if (_day == 31 && _month == 10) // Oct
{
_day = 1;
_day = _day - 1;
_month = 11;
}
if (_day == 30 && _month == 11) // Nov
{
_day = 1;
_day = _day - 1;
_month = 12;
}
if (_day == 31 && _month == 12) // Dec
{
_day = 1;
_month = 1;
_year = _year + 1;
}
else
{
_day = _day + 1;
}
}
}
public int Year // property called Year
{
get { return _year; } // return the year
set // set statement
{
if (value >= 1820 && value <= 2020) // if value is higher than or equal to 1820 and less than or equal to 2020
_year = value; // sets year as value
else
throw new ArgumentOutOfRangeException("Year must be between 1820 and 2020"); // throws an exception
}
}
public int Month // property called Month
{
get { return _month; } // return month
set // set statement
{
if (value > 0 && value <= 12) // if value is higher than 0 and less than or equal to 12
_month = value; // sets month as value
else
throw new ArgumentOutOfRangeException("Month must be between 1-12"); // throws an exception
}
}
public int Day // property called Day
{
get { return _day; }
set
{
// array Max days of each month
int[] days = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
if (value > 0 && value <= days[_month]) // if value is higher than 0 and less than or equal to days of month
_day = value; // sets day as value
// check for the leap year
else if (_month == 2 && value == 29 && // else if month is equal to 2 and value is equal to 29
(_year % 400 == 0 || (_year % 4 == 0 && _year % 100 != 0)))
_day = value;
else
throw new ArgumentOutOfRangeException("Day is out of range"); // throws an exception
}
}
}
}
}
There are several issues:
Each if block is being evaluated independently:
if (...)
{
}
if (...)
{
}
else
{
}
The else block here is only paired with the if block before it. Instead, you should be using else if in the middle ones.
After you make the above change, then you can remove the extraneous _day = _day - 1; calls.
The February check needs to account for leap year.
if (_day == 28 && _month == 2)
Should be
if (_month == 2 && (_day == IsLeapYear(_year) ? 29 : 28))
If you don't want to use DateTime.IsLeapYear, then extract your implementation from the Day setter into a method and use it in both places.
Regarding your question:
Whenever I remove the array within my Day property...
The only array in your Day property is the one called days, which you are indeed using correctly in your logic, so it doesn't make sense to remove it.
In a month i want to know mondays to sataurdays for the current month eg: in oct month 2011 there are
3-oct-2011 to 8-oct-2011,
10-OCt-11 to 15-Oct-11,
17-Oct-11 to 22-oct-2011,
24-Oct-2011 to 29-Oct-2011
all these sequence of days All these days like 3-oct-2011,4-oct-2011 ....29-oct-11 etc need to get in the array format or in the datatable.
var today = DateTime.Today;
var daysInMonth = DateTime.DaysInMonth(today.Year, today.Month);
var dates = Enumerable.Range(1, daysInMonth)
.Select(n => new DateTime(today.Year, today.Month, n))
.Where(date => date.DayOfWeek != DayOfWeek.Sunday)
.ToArray();
This will look at the number of days in the current month, create a DateTime object for each, then only return those dates which are not a Sunday as an array.
var today = DateTime.Today;
var daysInMonth = DateTime.DaysInMonth(today.Year, today.Month);
var dates = Enumerable.Range(1, daysInMonth)
.Select(n => new DateTime(today.Year, today.Month, n))
.Where(date => date.DayOfWeek != DayOfWeek.Sunday)
.SkipWhile(date => date.DayOfWeek != DayOfWeek.Monday)
.TakeWhile(date => date.DayOfWeek != DayOfWeek.Monday || (date.DayOfWeek == DayOfWeek.Monday && daysInMonth - date.Day > 7))
.ToArray();
This will do the same, except get rid of any Monday -> Saturday ranges which are not in the current month. (Week started in the previous month, or ends in the next).
Edit:
Here is a .NET 2 solution which will do the same thing as my previously posted LINQ solution.
DateTime today = DateTime.Today;
int daysInMonth = DateTime.DaysInMonth(today.Year, today.Month);
List<DateTime> dates = new List<DateTime>();
bool foundFirst = false;
for (int n = 1; n <= daysInMonth; n++)
{
var date = new DateTime(today.Year, today.Month, n);
// Skip untill we find the first Monday of the month.
if (date.DayOfWeek != DayOfWeek.Monday && !foundFirst)
continue;
foundFirst = true;
// Add all days except Sundays.
if (date.DayOfWeek != DayOfWeek.Sunday)
dates.Add(date);
int remainingDays = daysInMonth - n;
// Verify that there are enough days left in this month to add all days upto the next Saturday.
if (date.DayOfWeek == DayOfWeek.Saturday && remainingDays < 7)
break;
}
DateTime[] dateArray = dates.ToArray();
most easy:
int month = DateTime.Now.Month;
int year = DateTime.Now.Year;
int days= DateTime.DaysInMonth(year, month);
int totalSaturdays = 0;
for(int i=1;i<=days;i++)
{
var day = new DateTime(year, month, i);
if(day.DayOfWeek==DayOfWeek.Saturday)
{
totalSaturdays++;
}
}
Console.WriteLine(("Total Saturdays ="+totalSaturdays.ToString()));
Console.ReadLine();
Efficient solution;
var x = DateTime.DaysInMonth(DateTime.Now.Year, DateTime.Now.Month);
int i = 1;
while (i <= x)
{
if (new DateTime(DateTime.Now.Year, DateTime.Now.Month, i).DayOfWeek == DayOfWeek.Saturday)
{
Console.WriteLine(new DateTime(DateTime.Now.Year, DateTime.Now.Month, i));
i += 6;
}
i++;
}
I need to calculate the number of days between two dates (DateTime) but with a twist. I want to know how many days fall into each of the months that the two days span. Is there an easy way two do it?
Example:
I have start date 30/03/2011 and end date 05/04/2011 then the result should be something like:
var result = new Dictionary<DateTime, int>
{
{ new DateTime(2011, 3, 1), 2 },
{ new DateTime(2011, 4, 1), 5 }
};
You could try something like this:
using System;
using System.Collections.Generic;
static class Program {
// return dictionary tuple<year,month> -> number of days
static Dictionary<Tuple<int, int>, int> GetNumberOfDays(DateTime start, DateTime end) {
// assumes end > start
Dictionary<Tuple<int, int>, int> ret = new Dictionary<Tuple<int, int>, int>();
DateTime date = end;
while (date > start) {
if (date.Year == start.Year && date.Month == start.Month) {
ret.Add(
Tuple.Create<int, int>(date.Year, date.Month),
(date - start).Days + 1);
break;
} else {
ret.Add(
Tuple.Create<int, int>(date.Year, date.Month),
date.Day);
date = new DateTime(date.Year, date.Month, 1).AddDays(-1);
}
}
return ret;
}
static void Main(params string[] args) {
var days = GetNumberOfDays(new DateTime(2011, 3, 1), new DateTime(2011, 4, 1));
foreach (var m in days.Keys) {
Console.WriteLine("{0}/{1} : {2} days", m.Item1, m.Item2, days[m]);
}
}
}
You can use the class Month of the Time Period Library for .NET:
// ----------------------------------------------------------------------
public Dictionary<DateTime,int> CountMonthDays( DateTime start, DateTime end )
{
Dictionary<DateTime,int> monthDays = new Dictionary<DateTime, int>();
Month startMonth = new Month( start );
Month endMonth = new Month( end );
if ( startMonth.Equals( endMonth ) )
{
monthDays.Add( startMonth.Start, end.Subtract( start ).Days );
return monthDays;
}
Month month = startMonth;
while ( month.Start < endMonth.End )
{
if ( month.Equals( startMonth ) )
{
monthDays.Add( month.Start, month.DaysInMonth - start.Day + 1 );
}
else if ( month.Equals( endMonth ) )
{
monthDays.Add( month.Start, end.Day );
}
else
{
monthDays.Add( month.Start, month.DaysInMonth );
}
month = month.GetNextMonth();
}
return monthDays;
} // CountMonthDays
Usage:
// ----------------------------------------------------------------------
public void CountDaysByMonthSample()
{
DateTime start = new DateTime( 2011, 3, 30 );
DateTime end = new DateTime( 2011, 4, 5 );
Dictionary<DateTime, int> monthDays = CountMonthDays( start, end );
foreach ( KeyValuePair<DateTime, int> monthDay in monthDays )
{
Console.WriteLine( "month {0:d}, days {1}", monthDay.Key, monthDay.Value );
}
// > month 01.03.2011, days 2
// > month 01.04.2011, days 5
} // CountDaysByMonthSample
Simple yes, fast no:
DateTime StartDate = new DateTime(2011, 3, 30);
DateTime EndDate = new DateTime(2011, 4, 5);
int[] DaysPerMonth = new int[12];
while (EndDate > StartDate)
{
DaysPerMonth[StartDate.Month]++;
StartDate = StartDate.AddDays(1);
}
Here's my solution. I did a quick check and it seems to work... let me know if there are any problems:
public Dictionary<DateTime, int> GetMontsBetween(DateTime startDate, DateTime EndDate)
{
Dictionary<DateTime, int> rtnValues = new Dictionary<DateTime, int>();
DateTime startMonth = new DateTime(startDate.Year, startDate.Month, 1);
DateTime endMonth = new DateTime(EndDate.Year, EndDate.Month, 1);
//some checking
if (startDate >= EndDate)
{
rtnValues.Add(startMonth, 0); // Or return null;
}
else if (startDate.Month == EndDate.Month && startDate.Year == EndDate.Year)
{
rtnValues.Add(startMonth, EndDate.Day - startDate.Day);
}
else
{
//Add first month remaining days
rtnValues.Add(startMonth, DateTime.DaysInMonth(startDate.Year, startDate.Month) - startDate.Day);
//Add All months days inbetween
for (DateTime st = startMonth.AddMonths(1); st < endMonth; st = st.AddMonths(1))
{
rtnValues.Add(new DateTime(st.Year, st.Month, 1), DateTime.DaysInMonth(st.Year, st.Month) );
}
//Add last month days
rtnValues.Add(new DateTime(EndDate.Year, EndDate.Month, 1), EndDate.Day);
}
return rtnValues;
}
Little example of how we can accurately get the total months and days between 2 dates using the built-in DateTime.DaysInMonth method which gives us the number of days in each month so we can get 100% accuracy.
DateTime date1 = DateTime.Now.AddDays(60);
DateTime date2 = DateTime.Now;
TimeSpan ts = date1 - date2;
int totalDays = int.Parse(ts.TotalDays.ToString("0"));
int totalMonths = Math.Abs((date1.Month - date2.Month) + 12 * (date1.Year - date2.Year));
int months = 0;
int days = 0;
int totalDaysInMonths = 0;
for (int i = totalMonths; i > 0; i--)
{
int month = date2.Month + i;
int year = date1.Year;
if (month > 12)
{
year++;
int newMonth = month - 12;
month = newMonth;
}
totalDaysInMonths = totalDaysInMonths + DateTime.DaysInMonth(year, month);
}
if (totalDays > totalDaysInMonths)
{
months = totalMonths - 1;
days = totalDays - totalDaysInMonths;
}
else if (totalDays < totalDaysInMonths)
{
months = totalMonths - 1;
int tempTotalDaysInMonths = 0;
for (int i = months; i > 0; i--)
{
int month = date2.Month + i;
int year = date1.Year;
if (month > 12)
{
year++;
int newMonth = month - 12;
month = newMonth;
}
tempTotalDaysInMonths = tempTotalDaysInMonths + DateTime.DaysInMonth(year, month);
}
days = totalDays - tempTotalDaysInMonths;
}
else
{
months = totalMonths;
}
return string.Format("{0} months and {1} days", months, days);
A very quick and dirty run at it using linqpad:
DateTime start = DateTime.Parse("03/30/2011");
DateTime end = new DateTime(2011,04,05,23,59,59);
var startNextMonthFirstDay = new DateTime(start.Year, start.Month+1, 1);
var diffForStartMonth = (startNextMonthFirstDay - start);
var totalDiff = (end-start);
var diff = Math.Round(totalDiff.TotalDays);
var diffForEndMonth = diff - diffForStartMonth.Days;
Dictionary<DateTime, int> result = new Dictionary<DateTime, int>();
result.Add(new DateTime(start.Year, start.Month, 1), diffForStartMonth.Days);
result.Add(new DateTime(end.Year, end.Month, 1), (int)diffForEndMonth);
//Dictionary<DateTime,int>{{new DateTime(2011,3,1),2},{new DateTime(2011,4,1),5}}
result.Dump();
DateTime dt1 = new DateTime(2011, 12, 12);
DateTime dt2 = new DateTime(2011, 06, 12);
TimeSpan ts = dt1.Subtract(dt2);
String s = ts.Days.ToString();
MessageBox.Show(s);