.net 2.0 - 检查日期范围在 C# 中是否为顺序

本文关键字:是否 顺序 范围 检查 日期 net | 更新日期: 2023-09-27 17:55:14

>假设我有一个用户界面,用户可以在其中选择天数。 有没有办法检查所选日期是否是连续的,例如:

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

.net 2.0 - 检查日期范围在 C# 中是否为顺序

我不

相信有内置的方法可以实现您想要的结果,但是如果您可以轻松分辨最早和最晚的日期,您可以通过从最新日期中减去最早的日期来创建新的 TimeSpan,然后验证时间跨度的天数是否与所选日期的数量匹配 - 1。

你没有告诉我们天数是否按顺序排列。

你没有告诉我们他们是否会像在一个月内下降一样落在一个月的边界上

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

请注意,此解决方案只需要遍历序列一次。如果您没有有序序列,或者如果您允许落在一个月的边界上,则解决方案会更复杂。

没有内置内容,但您可以使用 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);

编辑 - 误解问题首先意味着时间升序而不是顺序 - 修复了这一点。

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

可以使用适用于 .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