验证日期时间按月连续

发布于 2024-07-30 13:19:37 字数 529 浏览 3 评论 0原文

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

例如,以下日期列表是有效的,因为它们增加一个月且没有缺失:

2009 年 1 月
2009 年 2 月
2009 年 3 月
2009 年 4 月

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

2009 年 1 月
2009 年 3 月
2009 年 4 月

日期并不重要,只考虑

有没有一种有效/漂亮的方法来做到这一点?

I have a list containing 60 DateTime objects (sorted in ascending order) and need to validate that each date is 1 month greater than the previous one in the list.

For example, the following list of dates would be valid because they increment by one month with none missing:

Jan-2009
Feb-2009
Mar-2009
Apr-2009

However, the following list of dates would be invalid because Feb-2009 is missing:

Jan-2009
Mar-2009
Apr-2009

The day doesn't matter, just the month and year are considered.

Is there an efficient/pretty way of doing this?

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

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

发布评论

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

评论(4

情未る 2024-08-06 13:19:37

对于所有日期,如果采用(年 * 12 + 月),您将得到一个连续的整数列表。 这可能更容易检查间隙。

For all of the dates, if you take (year * 12 + month) you'll get a sequential list of integers. That might be easier to check for gaps.

过潦 2024-08-06 13:19:37

您可以尝试以下操作:

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 进行比较,这是第一个计算值。

You could try the following:

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

This 'converts' the list of dates into a number that represents the Year and Month, which should be incrementing by 1 for each item in the list. We then subtract the current index from each of those items, so for a valid list, all items would have the same value. We then compare all values to start, which is the first computed value.

春花秋月 2024-08-06 13:19:37

这是一个干净的检查,使用精心设计的选择器,该选择器将根据您的用例进行正确比较:

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

Here's a clean check, making use of a carefully crafted selector that will compare correctly for your use case:

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

Using this custom 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);
}
诠释孤独 2024-08-06 13:19:37
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;
}
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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文