2010-10-08 11 views
7

Ich habe das folgende Snippet, das ich verwende, um die einzelnen Termine zwischen zwei Daten zu erhalten:Reihe von Monaten zwischen zwei Terminen

DateTime[] output = Enumerable.Range(0, 1 + endDate.Subtract(startDate).Days) 
    .Select(offset => startDate.AddDays(offset)) 
    .ToArray(); 

jedoch dem folgenden Abschnitt

endDate.Subtract(startDate).Days 

kein habe .Monate, um die Monate im Datumsbereich zurückzugeben.

Zum Beispiel, wenn ich 1/1/2010 und 6/1/2010 bereitstellen würde ich erwarten, 1/1/2010, 2/1/2010, 3/1/2010, 4/1/2010 zurückzukehren, 01.05.2010 und 01.06.2010

Irgendwelche Ideen?

+0

Wie würde ein 'Monate' Eigentum funktionieren? Wie würde es wissen, welche Tage des Monats verwendet werden? Nach der Subtraktion bleibt nur noch eine TimeSpan übrig, die datumsneutral ist und somit nichts über die zu verwendenden Monate weiß. –

+0

mögliches Duplikat von [Differenz in Monaten] (http: // stackoverflow.com/questions/1525990/Differenz in Monaten) –

+0

'.Days' gibt die ** Anzahl der Tage ** im Intervall zurück, nicht die tatsächlichen Tage. Wie definieren Sie die Tatsache, dass "* ein Monat zwischen 2 Daten *" liegt? Der Monat hat ** mindestens 1 Tag ** in diesem Intervall? Der Monat hat ** alle Tage ** im Intervall? Wie müssen Sie einen Monat mit einer 'DateTime'-Struktur darstellen? - als 1. des Monats? – CyberDude

Antwort

25

Try this:

static IEnumerable<DateTime> monthsBetween(DateTime d0, DateTime d1) 
{ 
    return Enumerable.Range(0, (d1.Year - d0.Year) * 12 + (d1.Month - d0.Month + 1)) 
        .Select(m => new DateTime(d0.Year, d0.Month, 1).AddMonths(m)); 
} 

Dies sowohl der Startmonat und das Ende Monat umfasst. Dies findet, wie viele Monate es ist, und erstellt dann einen neuen DateTime basierend auf d0 Jahr und Monat. Das heißt, die Monate sind wie yyyy-MM-01. Wenn Sie möchten, dass es die Uhrzeit und den Tag von d0 enthält, können Sie new DateTime(d0.Year, d0.Month, 1).AddMonths(m) durch d0.AddMonths(m) ersetzen.

Ich sehe, dass Sie ein Array benötigen, in diesem Fall verwenden Sie einfach monthsBetween(..., ...).ToArray() oder setzen Sie .ToArray() innerhalb der Methode.

0

Ist das wonach Sie suchen? Die Anforderung ist sehr mehrdeutig.

DateTime[] calendarMonthBoundaries = Enumerable.Range(0, 1 + endDate.Subtract(startDate).Days) 
    .Select(offset => startDate.AddDays(offset)) 
    .Where(date => date.Day == 1) 
    .ToArray(); 
1

Sie könnten Schritten Monate aufzählen mit:

private static IEnumerable<DateTime> ByMonths(DateTime startDate, DateTime endDate) 
{ 
    DateTime cur = startDate; 

    for(int i = 0; cur <= endDate; cur = startDate.AddMonths(++i)) 
    { 
    yield return cur; 
    } 
} 

und dann ToArray() auf das nennen, wenn Sie ein Array wollen. Es ist ziemlich gut, Werte zu haben, die wahrscheinlich das sind, was man will; z.B. wenn Sie bei 31. Januar st starten werden Sie nächste Februar bekommen 28 th (oder 29 th in Schaltjahren), dann 31. März st, dann 30. April th und so weiter.

+0

DateTime [] Monate = ByMonths ({30/01/2013 12:00:00 AM}, {4/04/2013 12:00:00}). ToArray(); Dies gibt nur 3 Monate zurück (Jan, Feb, Mär), April fehlt. –

+0

@DaveLucre Ich bin mir nicht sicher, dass das eine schlechte Sache ist, weil ich nicht sicher bin, was genau die Anforderung in der Frage "zwischen" betrachtet. Es könnte sicherlich geändert werden, um April in diesem Fall zu berücksichtigen, ich weiß nur nicht, ob es sollte. –

3

Da ich nur das Jahr und den Monat zwischen zwei Daten brauchte, änderte ich Lasse Espeholt ein wenig. annehmen: d0 = 2012-11-03

d1 = 2013-02-05

Das Ergebnis wird so etwas wie dieses:

2012-11

2012-12

2013-01

2013-02

private List<Tuple<int,int>> year_month_Between(DateTime d0, DateTime d1) 
    { 
     List<DateTime> datemonth= Enumerable.Range(0, (d1.Year - d0.Year) * 12 + (d1.Month - d0.Month + 1)) 
         .Select(m => new DateTime(d0.Year, d0.Month, 1).AddMonths(m)).ToList(); 
    List<Tuple<int, int>> yearmonth= new List<Tuple<int,int>>(); 

     foreach (DateTime x in datemonth) 
     { 
      yearmonth.Add(new Tuple<int, int>(x.Year, x.Month)); 
     } 
     return yearmonth; 
    } 
Verwandte Themen