2016-04-22 19 views
22

Chciałbym uzyskać daty między dwiema datami. Zamiast oczekiwanych różnych dat, otrzymuję i zabraknie pamięci. Jaki byłby problem z poniższym kodem?Jak uzyskać daty między dwoma datami w C#

StartDate wartość 01/04/2016 00:00:00

EndDate wartość jest 10/04/2016 00:00:00

var selectedDates = new List<DateTime?>(); 
for (var date = StartDate; date <= EndDate; date.Value.AddDays(1)) 
{ 
    selectedDates.Add(date); 
} 
+2

@JanesAbouChleih Przeprosiny, zmęczony mózg, nie widziałem, jak otrzymywały nieskończoną pętlę – Draken

+1

Prawdopodobny duplikat * [Pierwsze wszystkie DateTimes między dwoma "DateTime w C#] (http://stackoverflow.com/questions/3227927/ get-all-datetimes-between-two-datetimes-in-c-sharp) * –

Odpowiedz

35

Nie przypisujemy wartość date.Value.AddDays(1) do niczego, więc kończy się w nieskończonej pętli. Musisz zmienić kod, aby date ustawiono na wynik AddDays.

for (var date = StartDate; date <= EndDate; date = date.AddDays(1)) 
{ 
    selectedDates.Add(date); 
} 
+0

To. Podobnie jak 'String', manipulacje obiektami' DateTime' zwracają _new object_ zamiast modyfikowania istniejącego. – Nyerguds

+0

Na podstawie wyjaśnienia OP (co oznacza, że ​​ten kod się kompiluje i działa), ta 'data' wygląda jak' DateTime?', a nie' DateTime', ponieważ 'DateTime' nie ma właściwości o nazwie' Value'. –

+0

Zaktualizowany kod nie jest kompilowany, ponieważ 'Nullable ' nie ma metody o nazwie 'AddDays'. –

12

O ile widzę, ponieważ AddDays metoda zwraca nową instancję DateTime, robi nie zmienić bieżące wystąpienie od DateTime jest immutable.

Wygląda tak, jakby Twój date jest DateTime?, możesz zmienić tę część jako;

for (var date = StartDate; date <= EndDate; date = date.Value.AddDays(1)) 
{ 
    selectedDates.Add(date); 
} 

Jak usr spiczasty, to może mieć wpływ na DST. Możesz również sprawdzić Dmitry's answer.

+0

Czy to nie błąd z powodu przyrostowego charakteru obliczeń? Jeśli StartDate jest o 2:30 AM, czas się zmieni, jeśli kiedykolwiek trafisz na dzień letni. AddDays nie zachowuje się jak liczba całkowita. – usr

+0

@usr Masz rację, struktura 'DateTime' nie _nie bierze pod uwagę DST w operacjach arytmetycznych. Jednak w oparciu o daty rozpoczęcia i zakończenia OP nie powinno tak być. Zaktualizowałem także moją odpowiedź na odpowiedź Dmitry'ego. Dziękuję Ci. –

+0

Wykonanie tego jest okropne, ponieważ wiele razy rozszerza listę. – jessehouwing

1

postanowił zmienić go z do/podczas

var selectedDates = new List<DateTime?>(); 
DateTime? StartDate = DateTime.Parse("01/04/2016 00:00:00"); 
DateTime? EndDate = DateTime.Parse("10/04/2016 00:00:00"); 

do 
{ 
    selectedDates.Add(StartDate); 
    StartDate = StartDate.Value.AddDays(1); 
}while(StartDate < EndDate); 
23

LINQ rozwiązanie (powiedzmy generowaćselectedDates):

var selectedDates = Enumerable 
    .Range(0, int.MaxValue) 
    .Select(index => new DateTime?(StartDate.AddDays(index))) 
    .TakeWhile(date => date <= EndDate) 
    .ToList(); 
+1

To jest najlepsza odpowiedź, ponieważ pozwala uniknąć obliczeń przyrostowych, co jest wzorcem zapobiegającym. Nie jest nawet pewne, że idea 'AddDays (1)' jest nawet poprawna. – usr

+3

Dlaczego trzeba utworzyć nowy "DateTime?"? Jaki byłby problem z wyborem zwracanej wartości 'StartDate.AddDays (index)'? –

+2

@AshBurlaczenko: 'StartDate.AddDays' ma wartość zwracaną' DateTime', ale osoba pytająca użyła 'List ' w swoim pytaniu. 'new DateTime?' jest po prostu sposobem na wymuszenie zwracanej wartości na typ celu. –

5

Krótszy notacja stosując metodę LINQ wahają wykorzystuje zdolność aby dowiedzieć się, ile dni korzysta z właściwości TimeSpan.Days po odjęciu początku od końca.

Zakładając, że start jest przed końcem chcesz skończyć z:

DateTime StartDate = new DateTime(1979, 10, 4); 
DateTime EndDate = new DateTime(2016, 10, 4); 

var dates = Enumerable.Range(0, (EndDate - StartDate).Days + 1) 
    .Select(day => StartDate.AddDays(day)) 

jeśli jest to potrzebne, aby być Nullable, dodać:

.Cast<DateTime?>() 

Jeśli trzeba, że ​​jest to List, dodaj:

.ToList() 

Prawdopodobnie jest to trochę bardziej wydajne niż inne rozwiązanie oparte na LINQ.

Powiązane problemy