2010-10-08 11 views
7

Mam następujący fragment kodu, że mogę używać, aby uzyskać poszczególne daty pomiędzy dwiema datami:Utwórz tablicę miesięcy między dwiema datami

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

jednak następującą sekcję

endDate.Subtract(startDate).Days 

nie posiada .Miesiące, aby zwrócić miesiące w zakresie dat.

Na przykład, jeśli dostarczę 1/1/2010 i 6/1/2010, spodziewam się, że zwrócę 1/1/2010, 2/1/2010, 3/1/2010, 4/1/2010, 5/1/2010 i 6/1/2010.

Wszelkie pomysły?

+0

Jak działa właściwość 'Months'? Jak by się dowiedział, z którego # miesiąca korzystać? Po odjęciu pozostajesz z TimeSpan, który jest neutralny pod względem daty, a zatem nie wie nic o tym, które miesiące wykorzystać. –

+0

możliwy duplikat [Różnica w miesiącach] (http: // stackoverflow.com/questions/1525990/difference-in-months) –

+0

'.Days' zwraca ** liczbę dni ** w przedziale, a nie rzeczywiste dni. Jak definiujesz fakt, że "* miesiąc jest pomiędzy 2 datami *"? Miesiąc ma ** co najmniej 1 dzień ** w tym przedziale? Miesiąc ma ** wszystkie dni ** w przedziale? Również w jaki sposób należy reprezentować miesiąc przy użyciu struktury 'DateTime'? - jako 1 dzień miesiąca? – CyberDude

Odpowiedz

25

Spróbuj tego:

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

Obejmuje to zarówno miesiąc rozpoczynający i kończący miesiąc. Wykrywa to, ile miesięcy istnieje, a następnie tworzy nowy DateTime na podstawie roku i miesiąca d0. Oznacza to, że miesiące są jak yyyy-MM-01. Jeśli chcesz, aby zawierał czas i dzień d0, możesz zastąpić new DateTime(d0.Year, d0.Month, 1).AddMonths(m) przez d0.AddMonths(m).

Widzę, że potrzebujesz tablicy, w tym przypadku po prostu użyj monthsBetween(..., ...).ToArray() lub wstaw .ToArray() do metody.

0

Czy tego właśnie szukasz? Wymóg jest bardzo niejednoznaczny.

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

Można wyliczyć przyrosty miesięcy z:

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

a następnie zadzwonić ToArray() on, że jeśli chcesz tablicę. Jest dość dobrze, jeśli chodzi o posiadanie wartości, które prawdopodobnie będą potrzebne; na przykład jeśli zaczynają się od sty 31 st będziesz następny dostać 28 lut th (lub 29 TH w latach przestępnych), następnie Mar 31 st, następnie 30 kwietnia th i tak dalej.

+0

DateTime [] months = ByMonths ({30/01/2013 12:00:00 AM}, {4/04/2013 12:00:00 AM}). ToArray(); Powoduje to tylko 3 miesiące (jan, feb, mar), brakuje kwietnia. –

+0

@DaveLucre Nie jestem pewien, czy to źle, ponieważ nie jestem pewien, jakie wymaganie w pytaniu dotyczy "między". Z pewnością można by to zmienić, by w tym przypadku uwzględnić April, po prostu nie wiem, czy powinien. –

3

Ponieważ potrzebowałem właśnie roku i miesiąca pomiędzy dwiema datami, zmodyfikowałem Lasse Espeholt trochę. Przypuszczam: d0 = 2012-11-03

d1 = 2013-02-05

Rezultatem będzie coś takiego:

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; 
    } 
Powiązane problemy