2009-07-29 21 views
16

Ho un calendario che passa le date selezionate come stringhe in un metodo. All'interno di questo metodo, voglio generare un elenco di tutte le date a partire dalla data di inizio selezionata e che termina con la data di fine selezionata, ovviamente includendo tutte le date intermedie, indipendentemente dal numero di giorni tra le date di inizio e di fine selezionate.Come eseguire il ciclo tra due date

Di seguito è riportato l'inizio del metodo che utilizza le stringhe di data e le converte in variabili DateTime in modo che sia possibile utilizzare le funzioni di calcolo DateTime. Tuttavia, non riesco a capire come calcolare tutte le date tra la data di inizio e di fine? Ovviamente il primo passaggio consiste nel sottrarre la data di inizio dalla data di fine, ma non riesco a calcolare il resto dei passaggi.

aiuto apprezzato notevolmente,

saluti.

public void DTCalculations() 
{ 
List<string> calculatedDates = new List<string>(); 
string startDate = "2009-07-27"; 
string endDate = "2009-07-29"; 

//Convert to DateTime variables 
DateTime start = DateTime.Parse(startDate); 
DateTime end = DateTime.Parse(endDate); 

//Calculate difference between start and end date. 
TimeSpan difference = end.Subtract(start); 

//Generate list of dates beginning at start date and ending at end date. 
//ToDo: 
} 
+0

Il tuo passaggio noto tra valori generati (data, ora, minuto) –

risposta

33
static IEnumerable<DateTime> AllDatesBetween(DateTime start, DateTime end) 
{ 
    for(var day = start.Date; day <= end; day = day.AddDays(1)) 
     yield return day; 
} 

Edit: Aggiunto codice per risolvere il vostro esempio particolare, e per dimostrare l'uso:

var calculatedDates = 
    new List<string> 
    (
     AllDatesBetween 
     (
      DateTime.Parse("2009-07-27"), 
      DateTime.Parse("2009-07-29") 
     ).Select(d => d.ToString("yyyy-MM-dd")) 
    ); 
+2

Ho sempre la sensazione che la parola chiave yield sia troppo sotto utilizzata nella maggior parte dei popoli .net +1 per il punto sull'utilizzo! – MPritchard

+1

Per completezza, lo renderei statico anche – MPritchard

+0

Buon lavoro, perfetto –

2

La cosa più semplice da fare sarebbe prendere la data di inizio, e aggiungere 1 giorno per (usando AddDays) fino a raggiungere la data di fine. Qualcosa di simile a questo:

DateTime calcDate = start.Date; 
while (calcDate <= end) 
{ 
    calcDate = calcDate.AddDays(1); 
    calculatedDates.Add(calcDate.ToString()); 
} 

Ovviamente, si sarebbe regolare il tempo condizionale e la posizione delle AddDays chiamata a seconda se si vuole includere le date di inizio e fine della collezione o meno.

[Edit: A proposito, si dovrebbe considerare l'utilizzo di TryParse() al posto di Parse() nel caso in cui il passato in stringhe non convertire in date ben]

+0

Assicurati che la data di fine sia maggiore della data di inizio, in modo da non entrare in un ciclo infinito. :) –

+1

Greg, non dovresti controllare con == ma con <= –

1
for(DateTime i = start; i <= end; i = i.AddDays(1)) 
{ 
    Console.WriteLine(i.ToShortDateString()); 
} 
+0

Hai il significato di loop usando 'i' come variabile. Grazie per quello. –

4

Hai solo bisogno di scorrere da inizio alla fine, si può fare questo in un ciclo for

DateTime start = DateTime.Parse(startDate); 
DateTime end = DateTime.Parse(endDate); 

for(DateTime counter = start; counter <= end; counter = counter.AddDays(1)) 
{ 
    calculatedDates.Add(counter); 
} 
0

Un metodo alternativo

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

Ora nel codice chiamante è possibile effettuare le seguenti operazioni:

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

Un altro vantaggio di questo approccio è che rende banale aggiungere EachWeek, EachMonth ecc Questi saranno quindi accessibili in DateTime.