2016-07-13 7 views
-5

Ich versuche eine Logik zu knacken, aber bisher kein Glück. Brauchen Sie Ihre Unterstützung, um das Problem zu lösen. Ich muss die Anzahl der Tage berechnen, die in einem Monat zwischen Anfangs- und Enddatum auftreten.So erhalten Sie Monate und verbleibende Tage zwischen zwei Daten (d. H. Anfangs- und Enddatum)

im Detail zu erklären, finden Sie die Struktur-Eingang:

ID | Startdatum | Enddatum

1 | 15-Jan-16 | 15-Feb-16

2 | 23-Jan-16 | 15-Mar-16

Aus dem obigen Formular berechnet die Anwendung die Anzahl der Tage in einem bestimmten Monat. z.B. Für ID = 1 hat Jan 16 Tage und Feb 14 Tage. Das Formular wird in folgende Ausgabe übersetzt:

ID | Monat | Tage

1 | Jan | 16

1 | Feb | 14

2 | Jan | 8

2 | Feb | 29

2 | Mar | 13

Gibt es eine Möglichkeit, das Obige zu tun?

+4

Natürlich kann es. –

+0

Das liest sich wie eine Hausaufgabenfrage. Was hast du bisher versucht. Wo ist dein Code? – Igor

Antwort

1

Werfen Sie einen Blick auf TimeSpan.

Sie können damit ein Zeitintervall in Tagen, Stunden oder sogar Minuten darstellen.

0

Sie benötigen das Feld zu spalten, und dann die Daten zu analysieren, wie:

DateTime.ParseExact(text, 
    "dd-MMM-yy", 
    CultureInfo.InvariantCulture, 
    DateTimeStyles.AllowWhiteSpaces); 

Dann Schleife vom ersten Tag bis zum letzten Tag. Ich schlage vor, den ersten Tag des Startdatums auf den ersten Tag des letzten Datums für die Schleife zu setzen (andernfalls könnte der letzte Monat nicht ausgeführt werden, wenn der Tag des ersten Monats größer ist als der Tag des letzten Monats). Verwenden Sie die AddMonth (1) -Methode, um zu inkrementieren. Sie können die Anzahl der Tage in jedem Monat mit DateTime.DaysInMonth(year,month) erhalten.

Für den ersten Monat den Tag des ersten Datums von den Tagen im Monat subtrahieren.

Für den letzten Monat, subtrahieren Sie 1 vom Tag des letzten Datums.

Für die anderen Monate, wählen Sie einfach die Tage im Monat.

1

Ich glaube, die Ergebnisse, die Sie in Ihrer Frage gaben, sind falsch, aber das ist, wie Sie es tun können:

var obj = new[] { 
    new { ID=1, StartDate=new DateTime(2016,1,15), EndDate=new DateTime(2016,2,15) }, 
    new { ID=2, StartDate=new DateTime(2016,1,23), EndDate=new DateTime(2016,3,15) } 
}; 

var result=obj.SelectMany(x=> 
    Enumerable.Range(0,int.MaxValue) 
     .Select(m=>new DateTime(x.StartDate.Year,x.StartDate.Month,1).AddMonths(m)) 
     .TakeWhile(m=>m<x.EndDate) 
     .Select(m=>new { 
      x.ID, 
      //m.Year, 
      Month=m.ToString("MMM"), 
      Days=(x.EndDate.Year==m.Year && x.EndDate.Month==m.Month?x.EndDate.Day:DateTime.DaysInMonth(m.Year,m.Month)) 
      -(x.StartDate.Year==m.Year && x.StartDate.Month==m.Month?x.StartDate.Day:0) 
     }) 
); 

enter image description here

+0

Beachten Sie, dass in Ihrer Frage nicht angegeben wurde, wie Sie mit der Situation umgehen möchten, in der die Zeitspanne zwischen StartDate und EndDate länger als ein Jahr ist. Mein Code hält die Monate getrennt, aber es wäre trivial, die Jahre mehrerer Jahre zu einem einzigen "Days" -Wert zu kombinieren, wenn Sie das stattdessen benötigen. Die Antwort ignoriert auch, ob "EndDate" inklusive oder exklusiv ist, da Ihre Beispieldaten widersprüchlich sind. –

0

Hier ist eine Möglichkeit, es mit einer kleinen Hilfsmethode zu tun:

var data = ranges 
    .SelectMany(r => GetMonthlyDates(r.From, r.To) 
     .Select(m => new 
     { 
      r.ID, 
      MonthName = m.ToString("MMM"), 
      Days = m.Year == r.From.Year && m.Month == r.From.Month 
       ? DateTime.DaysInMonth(m.Year, m.Month) - m.Day 
       : (m.Year == r.To.Year && m.Month == r.To.Month ? r.To.Day : DateTime.DaysInMonth(m.Year, m.Month)) 
     })); 

private static IEnumerable<DateTime> GetMonthlyDates(DateTime from, DateTime to) 
{ 
    for (DateTime current = from; current.Year < to.Year || current.Month <= to.Month; current = current.AddMonths(1)) 
     yield return current; 
} 

Was mich gibt:

1 | Jan | 16 
1 | Feb | 15 
2 | Jan | 8 
2 | Feb | 29 
2 | Mar | 15 
Verwandte Themen