首页 > 解决方案 > 如何检查日期是否存在于一年中所有周的列表中

问题描述

我有一个 ASP.net C# 应用程序,它创建了给定年份中所有周的列表。例如选择 2019 年,并将生产 31/12/2019 至 06/01/2019 等。见附图。 在此处输入图像描述

为了产生这个,我从我在 Stack Overflow 上找到的一个例子中借用了一些代码

现在我还有另一个列表,其中包含 dd/MM/yyyy 格式的日期,这是从 XML 文件生成的,所以我只想显示与年份列表中日期匹配的周,并在何时填充下拉列表我的 XML 生成列表中的日期包含在其中。

例如,如果我的 XML 生成列表中有整整一周甚至一天的时间介于 2018 年 12 月 12 日到 2019 年 6 月 1 日之间,我想在下拉列表中显示它。同样,如果 XML 生成的列表不包含该周的至少一天,则不要显示它。

我已经粘贴了我用来获取下面给定年份的几周的代码。

我不确定有什么简单的方法可以比较这两个列表。任何帮助将不胜感激。

public List<string> FetchWeeks(int year)
{
    List<string> weeks = new List<string>();
    DateTime startDate = new DateTime(year, 1, 1);
    startDate = startDate.AddDays(1 - (int)startDate.DayOfWeek);
    DateTime endDate = startDate.AddDays(6);
    while (startDate.Year < 1 + year)
    {
        weeks.Add(string.Format("{0:dd/MM/yyyy} to {1:dd/MM/yyyy}", startDate, endDate));
        startDate = startDate.AddDays(7);
        endDate = endDate.AddDays(7);

    }
    //DropDownList1.Items.Add(weeks);
    return weeks;
}

标签: c#asp.netlist

解决方案


使用一些扩展函数和 LINQ,您可以直接从 XML Date 生成列表List<string>

首先,IEnumerable<>通过 lambda 函数选择 distinct 的扩展:

public static class IEnumerableExt {
    public static IEnumerable<T> DistinctBy<T, TKey>(this IEnumerable<T> src, Func<T, TKey> keySelector, IEqualityComparer<TKey> comparer = null) {
        var seenKeys = new HashSet<TKey>(comparer);
        foreach (var e in src)
            if (seenKeys.Add(keySelector(e)))
                yield return e;
    }
}

然后使用内置ISOWeek方法进行一些日历扩展来获取一年中的一周(根据您的周日期范围,我假设您使用的是 ISO 8601 周):

public static class CalendarExt {
    public static int GetISO8601WeekOfYear(this DateTime aDate) => ISOWeek.GetWeekOfYear(aDate);
    public static DateTime FirstDateOfYear(this DateTime d) => new DateTime(d.Year, 1, 1);
    public static DateTime FirstDateOfISO8601Week(this DateTime aDate) => aDate.AddDays(-(((int)aDate.DayOfWeek + 6) % 7));
    public static DateTime LastDateofISO8601Week(this DateTime aDate) => aDate.FirstDateOfISO8601Week().AddDays(6);    
    public static DateTime FirstDateOfISO8601Week(int year, int weekNum) => ISOWeek.ToDateTime(year, weekNum, DayOfWeek.Monday);
    public static DateTime LastDateofISO8601Week(int year, int weekNum) => FirstDateOfISO8601Week(year, weekNum).AddDays(6);    

    // for .Net without ISOWeek
    //public static DateTime FirstDateOfISO8601Week(this DateTime aDate) => aDate.AddDays(-(((int)aDate.DayOfWeek + 6) % 7));
    //public static int GetISO8601WeekOfYear(this DateTime aDate) =>
    //    CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(aDate.AddDays(DayOfWeek.Monday <= aDate.DayOfWeek && aDate.DayOfWeek <= DayOfWeek.Wednesday ? 3 : 0), CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
}

最后,给定来自 XML in 的字符串日期列表xmlDateStrings,您可以计算周范围列表:

var currentCulture = CultureInfo.CurrentCulture;
var ans = xmlDateStrings.Select(ds => DateTime.ParseExact(ds, "dd/MM/yyyy", currentCulture))
                        .DistinctBy(d => d.GetISO8601WeekOfYear())
                        .OrderBy(d => d) // assume XML is unsorted
                        .Select(d => $"{d.FirstDateOfISO8601Week().ToString("dd/MM/yyyy")} to {d.LastDateofISO8601Week().ToString("dd/MM/yyyy")}")
                        .ToList();

推荐阅读