c# - 如何检查日期是否存在于一年中所有周的列表中
问题描述
我有一个 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;
}
解决方案
使用一些扩展函数和 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();
推荐阅读
- shell - 为什么直线 CLI 参数在连接到直线 CLI 后不执行任何操作?
- r - 使用波浪号 (~) 的多个因变量
- c# - 返回具有匹配 id 的字段(特定 id)
- docker - 无法在 ubuntu 上使用 EFK 堆栈获取 Kubernetes 集群的日志
- sql - 如何选择一致的中间字符串
- python - 如何使用图像的每个像素的值绘制 3d 图形?
- python - python sqlite创建表语法错误
- telerik - Telerik RadGrid 滚动分页问题
- node.js - HTML to PDF with node-wkhtmltopdf 在 Digital Ocean Droplet 服务器上崩溃
- html - Rails 根据条件在 html 代码上包装 link_to