假设我有一个用户界面,用户可以选择日期。有没有办法检查所选日期是否是连续的,例如:
4 / 4,4 / 5,4 / 6,4 / 7,4 / 8,4 / 9,4 / 10或
4 / 29,4 / 30,5 / 1,5 / 2,5 / 3
我知道我可能会循环查看日期范围并检查,但是如果有一个内置方法已经检查过这个我更好奇。
关于上述情况,它们是有序的,它们可以翻到下个月。
我使用的是.NET Framework 2.0,无法使用LINQ。
关于汤姆的回答:
DateTime dtStart = new DateTime(2011,5,4);
DateTime dtEnd = new DateTime(2011,5,11);
int numberOfDaysSelected = 7; //Assume 7 days were selected.
TimeSpan ts = dtEnd - dtStart;
if(ts.Days == numberOfDaysSelected - 1)
{
Console.WriteLine("Sequential");
}
else
{
Console.WriteLine("Non-Sequential");
}
答案 0 :(得分:11)
我不相信有一种内置方法可以实现您想要的结果,但如果您可以轻松告诉最早和最晚的日期,您可以通过从最新日期减去最早的日期然后验证该日期来创建新的TimeSpan时间跨度的天数与所选日期的数量相匹配 - 1.
答案 1 :(得分:2)
您没有告诉我们是否订购了这些日子。
你没有告诉我们他们是否可能会超过一个月的边界,如
30, 31, 1.
我会假设有序,我会假设它们不会超过一个月的边界(因为你的例子是有序的,它不会超过一个月的边界)。
然后你可以说
public bool IsSequential(this IEnumerable<DateTime> sequence) {
Contract.Requires(sequence != null);
var e = sequence.GetEnumerator();
if(!e.MoveNext()) {
// empty sequence is sequential
return true;
}
int previous = e.Current.Date;
while(e.MoveNext()) {
if(e.Current.Date != previous.AddDays(1)) {
return false;
}
previous = e.Current.Date;
}
return true;
}
请注意,此解决方案只需要执行一次序列。如果您没有有序的序列,或者如果您允许超过一个月的边界,则解决方案会更复杂。
答案 2 :(得分:1)
没有内置但你可以使用Linq轻松构建一个:
List<DateTime> timeList = new List<DateTime>();
//populate list..
bool isSequential = timeList.Zip(timeList.Skip(1),
(a, b) => b.Date == a.Date.AddDays(1))
.All(x => x);
编辑 - 误解了问题首先意味着提升时间而不是连续 - 修正了。
答案 3 :(得分:1)
使用Linq的扩展方法:
public static bool IsContiguous(this IEnumerable<DateTime> dates)
{
var startDate = dates.FirstOrDefault();
if (startDate == null)
return true;
//.All() doesn't provide an indexed overload :(
return dates
.Select((d, i) => new { Date = d, Index = i })
.All(d => (d.Date - startDate).Days == d.Index);
}
测试它:
List<DateTime> contiguousDates = new List<DateTime>
{
new DateTime(2011, 05, 05),
new DateTime(2011, 05, 06),
new DateTime(2011, 05, 07),
};
List<DateTime> randomDates = new List<DateTime>
{
new DateTime(2011, 05, 05),
new DateTime(2011, 05, 07),
new DateTime(2011, 05, 08),
};
Console.WriteLine(contiguousDates.IsContiguous());
Console.WriteLine(randomDates.IsContiguous());
返回
True
False
修改强>:
.NET 2式答案:
public static bool CheckContiguousDates(DateTime[] dates)
{
//assuming not null and count > 0
var startDate = dates[0];
for (int i = 0; i < dates.Length; i++)
{
if ((dates[i] - startDate).Days != i)
return false;
}
return true;
}
答案 4 :(得分:0)
您可以使用Time Period Library for .NET的 TimeGapCalculator 来查找多个时间段之间的差距(与订单,计数和重叠无关):
// ----------------------------------------------------------------------
public void SequentialPeriodsDemo()
{
// sequential
ITimePeriodCollection periods = new TimePeriodCollection();
periods.Add( new Days( new DateTime( 2011, 5, 4 ), 2 ) );
periods.Add( new Days( new DateTime( 2011, 5, 6 ), 3 ) );
Console.WriteLine( "Sequential: " + IsSequential( periods ) );
periods.Add( new Days( new DateTime( 2011, 5, 10 ), 1 ) );
Console.WriteLine( "Sequential: " + IsSequential( periods ) );
} // SequentialPeriodsDemo
// --------------------------------------------------------------------
public bool IsSequential( ITimePeriodCollection periods, ITimePeriod limits = null )
{
return new TimeGapCalculator<TimeRange>(
new TimeCalendar() ).GetGaps( periods, limits ).Count == 0;
} // IsSequential