检查 C# 中的日期范围是否连续?

发布于 2024-11-05 02:29:27 字数 597 浏览 0 评论 0原文

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

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

Assume I have a user interface where the user can select days. Is there a way to check if the days selected are sequential, such as:

4/4, 4/5, 4/6, 4/7, 4/8, 4/9, 4/10 or

4/29, 4/30, 5/1, 5/2, 5/3

I know I probably can loop through the date range and check, but I was more curious if there was a built in method already to check for this.

Regarding the above scenarios, they are in order and they can roll over into the next month.

I am using the .NET Framework 2.0 and can't use LINQ.

Regarding Tom's answer:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

薯片软お妹 2024-11-12 02:29:27

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

I do not believe there is a built in method to achieve your desired results but if you can easily tell the earliest and latest dates, you could create a new TimeSpan by subtracting the the earliest date from the latest date and then verifying that the number of days of the timespan matches the number of dates selected - 1.

绮筵 2024-11-12 02:29:27

您没有告诉我们日期是否已定。

您没有告诉我们它们是否可能会超出一个月的边界,就像

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

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

You didn't tell us if the days are ordered.

You didn't tell us if they might fall over a month boundary as in

30, 31, 1.

I'll assume ordered, and I'll assume they won't fall over a month boundary (because your example is ordered, and it doesn't fall over a month boundary).

Then you can say

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

Note that this solution requires only walking the sequence once. If you don't have an ordered sequence, or if you permit falling over a month boundary the solution is more complicated.

温柔女人霸气范 2024-11-12 02:29:27

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

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

Nothing built in but you can build one easily using 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);

Edited - misunderstood question first to mean ascending in time as opposed to sequential - fixed that.

花开柳相依 2024-11-12 02:29:27

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

Extension method using 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);
}

Testing it:

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

Returns

True
False

EDIT:

.NET 2-like answer:

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;
}
风月客 2024-11-12 02:29:27

您可以使用时间的TimeGapCalculator .NET 的周期库用于查找多个时间段之间的间隙(与顺序、计数和重叠无关):

// ----------------------------------------------------------------------
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

You can use the TimeGapCalculator of the Time Period Library for .NET to find gaps between multiple time periods (independent of order, count and overlapping):

// ----------------------------------------------------------------------
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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文