Как вы повторяете каждый день года? - PullRequest
35 голосов
/ 10 февраля 2009

Учитывая дату начала 01.01.2009 и дату окончания 31.12.2009, как я могу перебрать каждую дату и получить значение DateTime, используя c #?

Спасибо!

Ответы [ 8 ]

78 голосов
/ 10 февраля 2009

Я бы использовал цикл, который выглядит следующим образом

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

Установите начало и конец соответственно

19 голосов
/ 10 февраля 2009

Еще один вариант реализации шаблона проектирования Iterator:

Это может показаться ненужным, но я, в зависимости от того, как вы используете эту функцию, вы также можете реализовать шаблон проектирования Iterator .

Подумай об этом. Предположим, что все работает отлично, и вы копируете / вставляете повсюду предложение «для». И внезапно, как часть требований, вы должны выполнить итерации всех дней, но пропустить некоторые из них (например, в календаре, пропустить выходные, выходные и т. Д.)

Вы должны будете создать новый "отрубленный" и использовать вместо него Календарь. Затем найдите и замените все ваши для.

В ООП этого можно достичь с помощью шаблона Iterator.

Из Википедии:

В объектно-ориентированном программировании шаблон Итератор является шаблоном проектирования, в котором итераторы используются для последовательного доступа к элементам агрегатного объекта без раскрытия его базового представления . Объект Iterator инкапсулирует внутреннюю структуру того, как происходит итерация.

Так что идея состоит в том, чтобы использовать такую ​​конструкцию:

        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 + " ");
        }

И затем, если необходимо, вы можете создать подклассы для реализации различных алгоритмов: один, использующий AddDay (1), другой, использующий AddDay (7), или другой, который вместо этого использует Calendar. И т. Д.

Идея состоит в том, чтобы уменьшить связь между объектами.

Опять же, это было бы излишним для большинства случаев, но если итерация образует релевантную часть системы (скажем, вы создаете какое-то какое-либо уведомление для предприятия, и следует придерживаться различных глобализаций

Базовая реализация, конечно, будет использовать 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;
        }
    }
}

Просто идея :)

6 голосов
/ 10 февраля 2009
DateTime dateTime = new DateTime(2009, 1, 1);    

while(dateTime.Year < 2010)
    {

      dateTime = dateTime.AddDays(1);
    }
5 голосов
/ 10 февраля 2009

Я бы использовал MiscUtil и методы его расширения:

foreach(DateTime date in 1.January(2009)
                         .To(31.December(2009))
                         .Step(1.Days())
{
    Console.WriteLine(date);
}
3 голосов
/ 10 февраля 2009

Установите две переменные:

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

Затем добавьте день к низкому значению, пока оно не станет равным старшему значению:

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

Или что-то в этом роде.

2 голосов
/ 07 февраля 2012

Альтернативный метод, который может быть более пригоден для повторного использования, - это написать метод расширения для 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))
{
    ...
}

Еще одним преимуществом этого подхода является то, что он делает тривиальным добавление EachWeek, EveryMonth и т. Д. Все они будут доступны в DateTime.

1 голос
/ 10 февраля 2009

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

Извините, не удержался.

0 голосов
/ 10 февраля 2009
DateTime current = DateTime.Parse("1/1/2009");
DateTime nextYear = current.AddYears(1);
do
{
    Console.WriteLine(current);
    current = current.AddDays(1);
} while (current < nextYear) ;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...