代码之家  ›  专栏  ›  技术社区  ›  Chris Conway

你如何迭代一年中的每一天?

  •  35
  • Chris Conway  · 技术社区  · 15 年前

    谢谢

    8 回复  |  直到 15 年前
        1
  •  84
  •   TK.    15 年前

    我会使用这样的循环

    for(DateTime date = begin; date <= end; date = date.AddDays(1))
    {
    }
    

    设置相应的开始和结束

        2
  •  22
  •   OscarRyz    11 年前

    实现迭代器设计模式的另一个选项:

    这听起来可能没有必要,但我认为,根据您如何使用此功能,您还可以实现 Iterator design pattern .

    想想这个。假设一切正常,你把“for”这个句子复制/粘贴到所有地方。突然之间,作为需求的一部分,您必须迭代所有的日期,但跳过其中的一些(如日历、跳过假日、周末、自定义等)

    您必须创建一个新的“剪贴”,并改用日历。然后搜索并替换所有的for。

    在OOP中,这可以使用迭代器模式实现。

    来自WikMedia:

    在面向对象编程中,迭代器模式是一种设计模式,其中迭代器用于按顺序访问聚合对象的元素 而不暴露其潜在的表现形式

    因此,我们的想法是使用如下构造:

            DateTime fromDate = DateTime.Parse("1/1/2009");
            DateTime toDate   = DateTime.Parse("12/31/2009");
    
            // Create an instance of the collection class
            DateTimeEnumerator dateTimeRange = 
                                  new DateTimeEnumerator( fromDate, toDate );
    
    
            // Iterate with foreach
            foreach (DateTime day in dateTimeRange )
            {
                System.Console.Write(day + " ");
            }
    

    其思想是降低对象之间的耦合。

    同样,这对于大多数情况来说都是过分的,但是如果迭代形成一个 相关的 系统的一部分(比如说,您正在为企业创建某种通知,并且应该遵循不同的全球化原则)

    当然,基本的实现将使用for。

    public class DateTimeEnumerator : System.Collections.IEnumerable
    {
        private DateTime begin;
        private DateTime end;
    
        public DateTimeEnumerator ( DateTime begin , DateTime end ) 
        {
            // probably create a defensive copy here... 
            this.begin = begin;
            this.end = end;
        }
        public System.Collections.IEnumerator GetEnumerator()
        {
            for(DateTime date = begin; date < end; date = date.AddDays(1))
            {
                yield return date;
            }
        }
    }
    

    只是一个想法:)

        3
  •  7
  •   kemiller2002    15 年前
    DateTime dateTime = new DateTime(2009, 1, 1);    
    
    while(dateTime.Year < 2010)
        {
    
          dateTime = dateTime.AddDays(1);
        }
    
        4
  •  5
  •   Jon Skeet    15 年前

    我会用 MiscUtil 及其扩展方法:

    foreach(DateTime date in 1.January(2009)
                             .To(31.December(2009))
                             .Step(1.Days())
    {
        Console.WriteLine(date);
    }
    
        5
  •  3
  •   John Sheehan    15 年前

    DateTime lowValue = DateTime.Parse("1/1/2009");
    DateTime highValue = DateTime.Parse("12/31/2009");
    

    然后,在低值上加上一天,直到它等于高值:

    while (lowValue <= highValue)
    {
       //Do stuff here
       lowValue = lowValue.AddDays(1);
    }
    

        6
  •  2
  •   Robert S.    15 年前

    int day; for (int i = 1; i<365;i++) { day++; }

    对不起,我无法抗拒。

        7
  •  2
  •   healsjnr    13 年前

    另一种更可重用的方法是在DateTime上编写扩展方法并返回IEnumerable。

    例如,您可以定义一个类:

    public static class MyExtensions
    {
        public static IEnumerable EachDay(this DateTime start, DateTime end)
        {
            // Remove time info from start date (we only care about day). 
            DateTime currentDay = new DateTime(start.Year, start.Month, start.Day);
            while (currentDay <= end)
            {
                yield return currentDay;
                currentDay = currentDay.AddDays(1);
            }
        }
    }
    

    DateTime start = DateTime.Now;
    DateTime end = start.AddDays(20);
    foreach (var day in start.EachDay(end))
    {
        ...
    }
    

    这种方法的另一个优点是,它使添加每个星期、每个月等变得很简单。然后这些都可以在DateTime上访问。

        8
  •  0
  •   DMCS    15 年前
    DateTime current = DateTime.Parse("1/1/2009");
    DateTime nextYear = current.AddYears(1);
    do
    {
        Console.WriteLine(current);
        current = current.AddDays(1);
    } while (current < nextYear) ;