Getting all DateTimes between two 'DateTime's in C#
I have two DateTime
s, and I want to get all DateTime
s between these Dates. Such as, if my Dates are like 01.01.2010 - 05.01.2010, my function should return me a list of date (List), and it must contain 01.01.2010, 02.01.2010, 03.01.2010, 04.01.2010, and 05.01.2010.
I wrote a function like this. It works fine, if my dates are in a month. It won't work if my dates are like 01.01.2010 - 05.02.2010. Because the month changed, and my function can't handle it. Is there a function in C# that returns all dates between two dates? Or how can I handle month change?
public void GetAllDatesAndInitializeTickets(DateTime startingDate, DateTime endingDate)
{
List<DateTime> allDates = new List<DateTime>();
int starting = startingDate.Day;
开发者_运维问答 int ending = endingDate.Day;
for (int i = starting; i <= ending; i++)
{
allDates.Add(new DateTime(startingDate.Year, startingDate.Month, i));
}
Question solved, see Tim Robinson's simple answer to use.
You can use DateTime
objects directly in the loop, in place of your int
. DateTime.AddDays
handles month ends correctly.
for (DateTime date = startingDate; date <= endingDate; date = date.AddDays(1))
allDates.Add(date);
How about something like this?
public IEnumerable<DateTime> DateRange(DateTime fromDate, DateTime toDate)
{
return Enumerable.Range(0, toDate.Subtract(fromDate).Days + 1)
.Select(d => fromDate.AddDays(d));
}
Edit: Tested now. :)
public IEnumerable<DateTime> GetAllDatesAndInitializeTickets(DateTime startingDate, DateTime endingDate)
{
if (endingDate < startingDate)
{
throw new ArgumentException("endingDate should be after startingDate");
}
var ts = endingDate - startingDate;
for (int i = 0; i < ts.TotalDays; i++)
{
yield return startingDate.AddDays(i);
}
}
You were so close... just don't use the day, use the whole date.
static IEnumerable<DateTime> GetAllDatesAndInitializeTickets(DateTime startingDate, DateTime endingDate)
{
List<DateTime> allDates = new List<DateTime>();
for (DateTime i = startingDate; i <= endingDate; i = i.AddDays(1))
{
allDates.Add(i);
}
return allDates.AsReadOnly();
}
Given a lowerdate value and higher date value in String and a frequency as the third parameter this method should return a dictionary of dates; where the key is the start value of a date range and the value is the respective range. This works fine if the frequency is either weekly or monthly- you can customize it as per your need. The date values passed should be in proper format or you might need to format it using tryParseExact or something like that.
protected static Dictionary<DateTime, String> getDateRange(String lowerDate, String higherDate, String frequency)
{
DateTime startDate, endDate;
startDate = Convert.ToDateTime(lowerDate);
endDate = Convert.ToDateTime(higherDate);
Dictionary<DateTime, String> returnDict = new Dictionary<DateTime, String>();
while (frequency.Equals("weekly") ? (startDate.AddDays(7) <= endDate) : (startDate.AddMonths(1) <= endDate))
{
if (frequency.Equals("weekly"))
{
returnDict.Add(startDate, startDate + "-" + startDate.AddDays(7));
startDate = startDate.AddDays(8);
}
if (frequency.Equals("monthly"))
{
returnDict.Add(startDate, startDate + "-" + startDate.AddMonths(1));
startDate = startDate.AddMonths(1).AddDays(1);
}
}
returnDict.Add(startDate, startDate + "-" + endDate);
return returnDict;
}
The top solutions will fail if the date includes different hours. Here is a solution getting all hours and all days:
All Days:
static public List<string> get_days_between_two_dates(DateTime start_date, DateTime end_date)
{
List<string> days_list = new List<string>();
DateTime temp_start;
DateTime temp_end;
//--Normalize dates by getting rid of minues since they will get in the way when doing the loop
temp_start = new DateTime(start_date.Year, start_date.Month, start_date.Day);
temp_end = new DateTime(end_date.Year, end_date.Month, end_date.Day);
//--Example Should return
//--1-12-2014 5:59AM - 1-13-2014 6:01AM return 12 and 13
for (DateTime date = temp_start; date <= temp_end; date = date.AddDays(1))
{
days_list.Add(date.ToShortDateString());
}
return days_list;
}
All Hours:
static public List<string> get_hours_between_two_dates(DateTime start_date, DateTime end_date)
{
List<string> hours_24_list = new List<string>();
DateTime temp_start;
DateTime temp_end;
//--Normalize dates by getting rid of minutes since they will get in the way when doing the loop
temp_start = new DateTime(start_date.Year, start_date.Month, start_date.Day, start_date.Hour, 0, 0);
temp_end = new DateTime(end_date.Year, end_date.Month, end_date.Day, end_date.Hour, 0, 0);
//--Example Should return
//--5:59AM - 6:01AM return 5am and 6am
for (DateTime date = temp_start; date <= temp_end; date = date.AddHours(1))
{
hours_24_list.Add(date.ToShortTimeString());
}
return hours_24_list;
}
Based on your starting code and using the features available at the time of writing, here is a quick console app to demonstrate how to do it - use AddDays()
instead:
class Program
{
static void Main(string[] args)
{
GetDates(new DateTime(2010, 1, 1), new DateTime(2010, 2, 5));
Console.ReadKey();
}
static List<DateTime> GetDates(DateTime startDate, DateTime endDate)
{
List<DateTime> dates = new List<DateTime>();
while ((startDate = startDate.AddDays(1)) < endDate)
dates.Add(startDate);
return dates;
}
}
Although I think the Enumerable.Range()
answer from Matt is a nicer solution.
static IEnumerable<DateTime> GetAllDatesAndInitializeTickets(DateTime startingDate, DateTime endingDate)
{
List<DateTime> allDates = new List<DateTime>();
for (DateTime i = startingDate; i <= endingDate; i = i.AddDays(1))
{
allDates.Add(i);
}
return allDates.AsReadOnly();
}
精彩评论