끔찍한 for 루프 / 카운터 유형 솔루션을 사용하지 않고이 작업을 수행하는 방법조차 확실하지 않습니다. 문제는 다음과 같습니다.
시작 날짜와 종료 날짜 두 가지가 주어지며 지정된 간격으로 조치를 취해야합니다. 예를 들어 : 2009 년 3 월 26 일까지 3 일마다 3/10/2009 사이의 모든 날짜에 대해 목록에 항목을 작성해야합니다. 내 입력은 다음과 같습니다.
DateTime StartDate = "3/10/2009";
DateTime EndDate = "3/26/2009";
int DayInterval = 3;
내 출력은 다음 날짜가있는 목록이됩니다.
2009 년 3 월 13 일 3/16/2009 3/19/2009 3/22/2009 3/25/2009
도대체 내가 어떻게 이런 짓을 할까? 나는 별도의 카운터를 사용하여 범위 내에서 매일 반복되는 for 루프를 사용하는 것에 대해 생각했습니다.
int count = 0;
for(int i = 0; i < n; i++)
{
count++;
if(count >= DayInterval)
{
//take action
count = 0;
}
}
그러나 더 좋은 방법이있을 것 같습니다?
답변
글쎄, 당신은 그것들을 어떤 식 으로든 반복해야합니다. 다음과 같은 방법을 정의하는 것을 선호합니다.
public IEnumerable<DateTime> EachDay(DateTime from, DateTime thru)
{
for(var day = from.Date; day.Date <= thru.Date; day = day.AddDays(1))
yield return day;
}
그런 다음 다음과 같이 사용할 수 있습니다.
foreach (DateTime day in EachDay(StartDate, EndDate))
// print it or whatever
이 방법으로 격일로, 매 3 일마다, 주중에만 등을 맞출 수 있습니다. 예를 들어 “시작”날짜로 시작하는 3 일마다 돌아가 AddDays(3)
려면 대신 루프를 호출 하면됩니다 AddDays(1)
.
답변
나는이 Range
클래스 MiscUtil 당신이 유용 할 수있다. 다양한 확장 방법과 결합하여 다음을 수행 할 수 있습니다.
foreach (DateTime date in StartDate.To(EndDate).ExcludeEnd()
.Step(DayInterval.Days())
{
// Do something with the date
}
(당신은 끝을 제외하고 싶거나 원하지 않을 수 있습니다. 나는 단지 그것을 예제로 제공한다고 생각했습니다.)
이것은 기본적으로 mquander 솔루션의 기성품 및보다 일반적인 형태입니다.
답변
당신의 예를 들어 당신은 시도 할 수 있습니다
DateTime StartDate = new DateTime(2009, 3, 10);
DateTime EndDate = new DateTime(2009, 3, 26);
int DayInterval = 3;
List<DateTime> dateList = new List<DateTime>();
while (StartDate.AddDays(DayInterval) <= EndDate)
{
StartDate = StartDate.AddDays(DayInterval);
dateList.Add(StartDate);
}
답변
@mquander 및 @Yogurt의 코드 확장에 사용되는 Wise :
public static IEnumerable<DateTime> EachDay(DateTime from, DateTime thru)
{
for (var day = from.Date; day.Date <= thru.Date; day = day.AddDays(1))
yield return day;
}
public static IEnumerable<DateTime> EachMonth(DateTime from, DateTime thru)
{
for (var month = from.Date; month.Date <= thru.Date || month.Month == thru.Month; month = month.AddMonths(1))
yield return month;
}
public static IEnumerable<DateTime> EachDayTo(this DateTime dateFrom, DateTime dateTo)
{
return EachDay(dateFrom, dateTo);
}
public static IEnumerable<DateTime> EachMonthTo(this DateTime dateFrom, DateTime dateTo)
{
return EachMonth(dateFrom, dateTo);
}
답변
DateTime startDate = new DateTime(2009, 3, 10);
DateTime stopDate = new DateTime(2009, 3, 26);
int interval = 3;
for (DateTime dateTime=startDate;
dateTime < stopDate;
dateTime += TimeSpan.FromDays(interval))
{
}
답변
1 년 후 누군가에게 도움이 되겠습니까?
이 버전에는 보다 유연한 술어가 포함 되어 있습니다.
용법
var today = DateTime.UtcNow;
var birthday = new DateTime(2018, 01, 01);
내 생일에 매일
var toBirthday = today.RangeTo(birthday);
내 생일에 매달 2 단계
var toBirthday = today.RangeTo(birthday, x => x.AddMonths(2));
매년 내 생일에
var toBirthday = today.RangeTo(birthday, x => x.AddYears(1));
사용 RangeFrom
하는 대신
// same result
var fromToday = birthday.RangeFrom(today);
var toBirthday = today.RangeTo(birthday);
이행
public static class DateTimeExtensions
{
public static IEnumerable<DateTime> RangeTo(this DateTime from, DateTime to, Func<DateTime, DateTime> step = null)
{
if (step == null)
{
step = x => x.AddDays(1);
}
while (from < to)
{
yield return from;
from = step(from);
}
}
public static IEnumerable<DateTime> RangeFrom(this DateTime to, DateTime from, Func<DateTime, DateTime> step = null)
{
return from.RangeTo(to, step);
}
}
엑스트라
의 경우 예외를 던질 수 fromDate > toDate
있지만 대신 빈 범위를 반환하는 것을 선호합니다.[]
답변
DateTime startDate = new DateTime(2009, 3, 10);
DateTime stopDate = new DateTime(2009, 3, 26);
int interval = 3;
while ((startDate = startDate.AddDays(interval)) <= stopDate)
{
// do your thing
}
