Получение всех дат между двумя ' DateTime в C#
у меня есть два DateTime
S, и я хочу получить все DateTime
s между этими датами. Например, если мои даты вроде 01.01.2010 - 05.01.2010, моя функция должна возвращать мне список дат (список), и он должен содержать 01.01.2010, 02.01.2010, 03.01.2010, 04.01.2010 и 05.01.2010.
Я написал такую функцию. Он отлично работает, если мои даты через месяц. Это не будет работать, если мои даты, как 01.01.2010 - 05.02.2010. За месяц изменилось, и моя функция не может справиться с этим. Есть функция в C#, которая возвращает все даты между двумя датами? Или как я могу справиться с изменением месяца?
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));
}
вопрос решен, см. простой ответ Тима Робинсона для использования.
8 ответов:
можно использовать
DateTime
объекты непосредственно в цикле, вместо вашегоint
.DateTime.AddDays
ручки месяц заканчивается правильно.for (DateTime date = startingDate; date <= endingDate; date = date.AddDays(1)) allDates.Add(date);
Как насчет чего-то вроде этого?
public IEnumerable<DateTime> DateRange(DateTime fromDate, DateTime toDate) { return Enumerable.Range(0, toDate.Subtract(fromDate).Days + 1) .Select(d => fromDate.AddDays(d)); }
Edit: протестировано сейчас. :)
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); } }
Вы были так близки... просто не используйте день, используйте всю дату.
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(); }
вот быстрый консольное приложение, чтобы продемонстрировать, как это сделать - используйте
AddDays()
вместо: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; } }
учитывая более низкое значение даты и более высокое значение даты в строке и частоту в качестве третьего параметра, этот метод должен возвращать словарь дат; где ключ-начальное значение диапазона дат, а значение-соответствующий диапазон. Это прекрасно работает, если частота либо еженедельно или ежемесячно - вы можете настроить его согласно вашей потребности. Переданные значения даты должны быть в правильном формате или вам может потребоваться отформатировать его с помощью tryParseExact или что-то в этом роде.
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; }
лучшие решения не удастся, если дата включает в себя различные часы. Вот решение, получающее все часы и все дни:
Все Дни:
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; }
Все Часы:
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; }