Ответ 1
Вы можете использовать объекты DateTime
непосредственно в цикле вместо вашего int
. DateTime.AddDays
правильно обрабатывает месяц.
for (DateTime date = startingDate; date <= endingDate; date = date.AddDays(1))
allDates.Add(date);
У меня есть два DateTime
s, и я хочу получить все DateTime
между этими датами. Например, если мои Даты похожи на 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. Потому что месяц изменился, и моя функция не может справиться с этим. Есть ли функция в С#, которая возвращает все даты между двумя датами? Или как я могу обрабатывать изменения месяца?
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));
}
Вопрос решен, см. Тим Робинсон, простой ответ на использование.
Вы можете использовать объекты 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));
}
Изменить: Протестировано сейчас.:)
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;
}
}
Учитывая значение нижнего значения и более высокое значение даты в String и частоту в качестве третьего параметра, этот метод должен возвращать словарь дат; где ключ - начальное значение диапазона дат, а значение - соответствующий диапазон. Это работает отлично, если частота является еженедельной или ежемесячной - вы можете настроить ее в соответствии с вашими потребностями. Переданные значения даты должны быть в правильном формате или вам может потребоваться отформатировать его с помощью 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;
}
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();
}