如何遍历日期范围?

one*_*ney 181 c# asp.net datetime loops

如果不使用一些可怕的循环/计数器类型解决方案,我甚至不确定如何做到这一点.这是问题所在:

我有两个日期,开始日期和结束日期,在指定的时间间隔内我需要采取一些行动.例如:对于2009年10月3日之间的每个日期,每隔三天至2009年3月26日,我需要在列表中创建一个条目.所以我的意见是:

DateTime StartDate = "3/10/2009";
DateTime EndDate = "3/26/2009";
int DayInterval = 3;
Run Code Online (Sandbox Code Playgroud)

我的输出将是一个具有以下日期的列表:

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;
     }

}
Run Code Online (Sandbox Code Playgroud)

但似乎可能有更好的方法?

mqp*_*mqp 439

好吧,你需要以这种或那种方式循环它们.我更喜欢定义这样的方法:

public IEnumerable<DateTime> EachDay(DateTime from, DateTime thru)
{
    for(var day = from.Date; day.Date <= thru.Date; day = day.AddDays(1))
        yield return day;
}
Run Code Online (Sandbox Code Playgroud)

然后你可以像这样使用它:

foreach (DateTime day in EachDay(StartDate, EndDate))
    // print it or whatever
Run Code Online (Sandbox Code Playgroud)

通过这种方式,您可以每隔一天,每隔三天,仅在工作日等时间点击等.例如,从"开始"日期开始每隔三天返回一次,您可以AddDays(3)在循环中调用而不是AddDays(1).

  • 您甚至可以为间隔添加另一个参数. (16认同)
  • 将此作为日期时间的扩展方法可能会使其更好. (9认同)
  • 一个非常好的解决方案,一个有趣和真实的单词问题.我喜欢它如何显示该语言的一些有用技巧.这让我想起for循环不仅仅是(int i = 0; ...)( - . (3认同)

Jon*_*eet 28

RangeMiscUtil中有一个你可以找到有用的课程.结合各种扩展方法,您可以:

foreach (DateTime date in StartDate.To(EndDate).ExcludeEnd()
                                   .Step(DayInterval.Days())
{
    // Do something with the date
}
Run Code Online (Sandbox Code Playgroud)

(你可能想也可能不想排除结尾 - 我只是想把它作为一个例子.)

这基本上是mquander解决方案的现成(并且更通用)形式.

  • 无论你是否喜欢这种扩展方法,当然只是一种品味问题.`ExcludeEnd()`很可爱. (2认同)

Adr*_*der 20

对于你的例子,你可以尝试

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);
}
Run Code Online (Sandbox Code Playgroud)

  • 我想我们需要StartDate.AddDays(DayInterval); 一次在此循环中不会两次. (3认同)

Jac*_*bus 12

来自@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);
}
Run Code Online (Sandbox Code Playgroud)


amd*_*amd 8

1年后,它可以帮助某人,

此版本包含一个谓词,更灵活.

用法

var today = DateTime.UtcNow;
var birthday = new DateTime(2018, 01, 01);
Run Code Online (Sandbox Code Playgroud)

每天到我的生日

var toBirthday = today.RangeTo(birthday);  
Run Code Online (Sandbox Code Playgroud)

每月到我的生日,步骤2个月

var toBirthday = today.RangeTo(birthday, x => x.AddMonths(2));
Run Code Online (Sandbox Code Playgroud)

每年到我的生日

var toBirthday = today.RangeTo(birthday, x => x.AddYears(1));
Run Code Online (Sandbox Code Playgroud)

RangeFrom改用

// same result
var fromToday = birthday.RangeFrom(today);
var toBirthday = today.RangeTo(birthday);
Run Code Online (Sandbox Code Playgroud)

履行

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

附加功能

如果是fromDate > toDate,你可以抛出一个Exception ,但我更喜欢返回一个空范围[]


gil*_*rtc 7

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))
{

}
Run Code Online (Sandbox Code Playgroud)


Sun*_*shi 6

DateTime begindate = Convert.ToDateTime("01/Jan/2018");
DateTime enddate = Convert.ToDateTime("12 Feb 2018");
 while (begindate < enddate)
 {
    begindate= begindate.AddDays(1);
    Console.WriteLine(begindate + "  " + enddate);
 }
Run Code Online (Sandbox Code Playgroud)