验证日期时间是按月递增的

时间:2009-08-06 19:50:07

标签: c# linq performance date compare

我有一个包含60个DateTime个对象的列表(按升序排序),需要验证每个日期比列表中的前一个日期大1个月。

例如,以下日期列表有效,因为它们会增加一个月而不会丢失:

  

2009年1月 - 2月 - 2009年3月 - 2月   APR-2009

但是,以下日期列表无效,因为2009年2月缺失:

  

2009年1月至2009年3月 - 2009年4月

这一天并不重要,只考虑

这样做是否有效/漂亮?

4 个答案:

答案 0 :(得分:8)

对于所有日期,如果你采取(年* 12 +月),你将得到一个整数的顺序列表。这可能更容易检查差距。

答案 1 :(得分:3)

您可以尝试以下方法:

int start = list.First().Year * 12 + list.First().Month;
bool sequential = list
    .Select((date, index) => date.Year * 12 + date.Month - index)
    .All(val => val == start);

这会将日期列表“转换”为表示年份和月份的数字,对于列表中的每个项目,该数字应递增1。然后我们从每个项目中减去当前索引,因此对于有效列表,所有项目都具有相同的值。然后,我们将所有值与start进行比较,这是第一个计算值。

答案 2 :(得分:1)

这是一个干净的检查,使用精心设计的选择器,可以正确比较您的用例:

IEnumerable<DateTime> dates = ...;
DateTime firstDate = dates.First();
IEnumerable desired = Enumerable.Range(0, 60).Select(months => firstDate.AddMonths(months));
bool correct = dates.SequenceEqual(desired, date => date.Year*12 + date.Month);

使用此自定义SequenceEqual

public static bool SequenceEqual<T1, T2>(this IEnumerable<T1> first, IEnumerable<T1> second, Func<T1, T2> selector)
{
    // uses the LINQ Enumerable.SequenceEqual method on the selections
    return first.Select(selector).SequenceEqual(second.Select(selector));
}

// this is also useful, but not used in this example
public static bool SequenceEqual<T1, T2>(this IEnumerable<T1> first, IEnumerable<T1> second, Func<T1, T2> selector, IEqualityComparer<T2> comparer)
{
    return first.Select(selector).SequenceEqual(second.Select(selector), comparer);
}

答案 3 :(得分:0)

public bool MonthsAreSequential(IList<DateTime> dates)
{
    if (dates.Count < 2) return true;

    for (int i = 0; i < dates.Count - 1; i++)
    {
        var plusOne = dates[i].AddMonth(1);
        var nextMonth = dates[i + 1];
        if (plusOne .Year != nextMonth .Year 
            || plusOne .Month != nextMonth .Month)
            return false;
    }
    return true;
}