我有一个c#列表,其中包含使用cDates类的句点。
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解决方案?
答案 0 :(得分: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;}
}
答案 1 :(得分: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
。
答案 2 :(得分: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();
否则,您需要展开{{1}}内的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
接口以枚举日期的类:
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