2014-12-29 48 views
0

我有一個包含使用cDates類的句點的c#列表。將句點列表轉換爲c中的日期列表#

public class cDates 
{ 
    public Date PeriodStart {get;set;} 
    public Date PeriodEnd {get;set;} 
} 


2014/01/01 - 2014/04/30 
2014/05/01 - 2014/07/31 
2014/08/01 - 2014/09/30 

是否有可能獲取包含現有期間中的所有日期的日期列表,如List。

public class cSingleDate 
{ 
      public Date SingleDate {get;set;} 
} 

    2014/01/01 
    2014/01/02 
    2014/01/03 
    ... 
    2014/09/30 

我試圖找到一個使用循環的解決方案,但想找出一個更清潔的解決方案。也許是Linq解決方案?

+1

什麼是'Dates'類型? –

+0

@FelipeOriani排字錯誤 – mko

+2

不要用「c」加前綴:[不要使用匈牙利符號](http://msdn.microsoft.com/en-us/library/ms229045(v = vs.110))。 aspx) – BCdotWEB

回答

3

您可以使用LINQ爲:

[TestMethod] 
public void TestPeriods() 
{ 
    var periods = new[] 
        { 
         new Period(new DateTime(2014, 01, 01), new DateTime(2014, 04, 30)), 
         new Period(new DateTime(2014, 05, 01), new DateTime(2014, 07, 31)), 
         new Period(new DateTime(2014, 08, 01), new DateTime(2014, 09, 30)), 
        }; 

    var days = from period in periods 
       let numberOfDays = (period.LastDay - period.FirstDay).Days + 1 
       from day in Enumerable.Range(0, numberOfDays) 
       select period.FirstDay.AddDays(day); 

    var distinctDays = days.Distinct().ToArray(); 

    distinctDays.Should().Contain(new DateTime(2014, 01, 01)); 
    distinctDays.Should().Contain(new DateTime(2014, 02, 01)); 
    distinctDays.Should().Contain(new DateTime(2014, 04, 30)); 
    distinctDays.Should().NotContain(new DateTime(2014, 10, 01)); 
} 

public class Period 
{ 
     public Period(DateTime firstDay, DateTime lastDay) 
     { 
      this.FirstDay = firstDay; 
      this.LastDay = lastDay; 
     } 

     public DateTime FirstDay {get;set;} 
     public DateTime LastDay {get;set;} 
} 
2

你可以通過日期循環,只要增加一天PeriodStart,因爲它是小於或等於PeriodEnd

var dates = new List<cSingleDate>(); 
foreach(var date in cDates) 
{ 
    while(date.PeriodStart <= date.PeriodEnd) 
    { 
     dates.Add(new cSingleDate { SingleDate = date.PeriodStart }); 
     date.PeriodStart = date.PeriodStart.AddDays(1); 
    } 
} 

如果你不想改變cDates只需使用一個臨時變量來存儲PeriodStart

+0

這跟我得到的差不多。我正在尋找更多的linq解決方案。 – mko

1

有兩種簡單的方法從Period類轉換日期,日期的一個列表。你可以擴展Period類來給你日期並使用linq來壓扁它,或者你用linq讀取兩個屬性。如果SingleDate類真的只存儲日期而沒有其他功能,並且它沒有提供任何附加功能,則可以考慮只提取日期。

// Test data. 
var periods = new[] 
{ 
    new Period(new DateTime(2014, 01, 01), new DateTime(2014, 04, 30)), 
    new Period(new DateTime(2014, 05, 01), new DateTime(2014, 07, 31)), 
    new Period(new DateTime(2014, 08, 01), new DateTime(2014, 09, 30)), 
}; 

如果你可以讓Period類來實現IEnumerable<DateTime>接口,從而拉平爲您的日期,然後簡單SelectMany可用於:

var result1 = 
    periods 
    // The Period class will enumerate the dates for SelectMany: 
    .SelectMany(x => x) 
    // Uncomment this line if you want to encapsulate the date. 
    //.Select(x => new SingleDate() { Date = x })  
    .ToList(); 

否則,你就必須彙整裏面的Period日期SelectMany

var resul2 = 
    periods 
    // Here SelectMany has to enumerate the dates: 
    .SelectMany(x => new[] 
    { 
     x.PeriodStart, 
     x.PeriodEnd 
    }) 
    // Uncomment this line if you want to encapsulate the date. 
    //.Select(x => new SingleDate() { Date = x }) 
    .ToList(); 

Period -class實現在IEnumerable<DateTime>接口來枚舉日期:

public class Period : IEnumerable<DateTime> 
{ 
    public Period(DateTime firstDay, DateTime lastDay) 
    { 
     this.PeriodStart = firstDay; 
     this.PeriodEnd = lastDay; 
    } 

    public DateTime PeriodStart { get; set; } 

    public DateTime PeriodEnd { get; set; } 

    public IEnumerator<DateTime> GetEnumerator() 
    { 
     yield return PeriodStart; 
     yield return PeriodEnd; 
    } 

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() 
    { 
     return GetEnumerator(); 
    } 
} 

SingleDate -class沒有改變(你不需要它,如果它不提供任何額外的功能):

public class SingleDate 
{ 
    public DateTime Date { get; set; } 
} 
+0

更新的代碼和說明。 – t3chb0t