C # список прошлых дат - PullRequest
3 голосов
/ 25 января 2010

У меня есть метод, который возвращает прошедшие x дни, и в настоящее время он выполняет следующие действия:

var dates = new List<DateTime>();

for (int i = 0; i < numDays; i++)
{
    dates.Add(DateTime.Today.AddDays(-i));
}

return dates;

Я чувствую, что должен быть более компактный способ сделать это, возможно, используя LINQ. Предложения? Кроме того, если я сохраню все как есть, будет ли DateTime.Today таким, что это будет более эффективным, если я сохраню его в переменной вне цикла и затем вызову AddDays для этого значения в цикле?

Редактировать: LINQ использует ленивый анализ, верно? Я получаю сумасшедшие образы в моей голове:

return DateTime.AllDaysInTheHistoryOfTimeEver.Where(day =>
    day.BeforeOrOn(DateTime.Today) &&
    day.After(DateTime.Today.AddDays(-numDays))
);

Ответы [ 4 ]

12 голосов
/ 25 января 2010
var start = DateTime.Today;
var days = Enumerable.Range(0, numDays).Select(i => start.AddDays(-i)).ToList();

Во время захвата start сначала избегается случайный запуск его около полуночи.

1 голос
/ 25 января 2010

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

Когда вы вызываете DateTime.Today, он возвращает UtcNow.ToLocalTime(), что добавляет немного больше накладных расходов обработки по сравнению с использованием даты, которая уже DateTimeKind.Local:

public virtual DateTime ToLocalTime(DateTime time)
{
    if (time.Kind == DateTimeKind.Local)
    {
        return time;
    }
    bool isAmbiguousLocalDst = false;
    long utcOffsetFromUniversalTime = ((CurrentSystemTimeZone) CurrentTimeZone).GetUtcOffsetFromUniversalTime(time, ref isAmbiguousLocalDst);
    return new DateTime(time.Ticks + utcOffsetFromUniversalTime, DateTimeKind.Local, isAmbiguousLocalDst);
}
1 голос
/ 25 января 2010

возможно не linq, но вы можете сделать это с помощью итератора, не уверенного в ваших точных требованиях (например, numDays), но нижеприведенное даст вам последние 10 дней.

var dates = GetDates(DateTime.Now.AddDays(-10),DateTime.Now);

 public IEnumerable<DateTime> GetDates(DateTime StartingDate, DateTime EndingDate)
        {
            while (StartingDate <= EndingDate)
            {
                yield return StartingDate;
                StartingDate = StartingDate.AddDays(1);
            }
        } 
0 голосов
/ 25 января 2010

Вместо сбора значений в списке вы можете вернуть IEnumerator или IEnumerable и использовать ключевое слово yield.

См. Статью MSDN

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...