C# 每周一次';s列表中的开始和结束日期<;日期时间>;使用LINQ
我有一个场景用户将输入开始日期和结束日期。我列出了该日期范围之间的C# 每周一次';s列表中的开始和结束日期<;日期时间>;使用LINQ,c#,linq,datetime,C#,Linq,Datetime,我有一个场景用户将输入开始日期和结束日期。我列出了该日期范围之间的DateTime 现在我有了一个序列的DateTime,比如说从本月1日到本月30日,我想在一个结果集中得到每周的开始和结束日期,如: WeekStartDate WeekEndDate 01/01/2015 04/01/2015 05/01/2015 11/01/2015 我曾尝试使用linq获得期望的结果,但我无法集中精力获得期望的输出,以下是我的尝试: var dating = from d i
DateTime
现在我有了一个序列的DateTime
,比如说从本月1日到本月30日,我想在一个结果集中得到每周的开始和结束日期,如:
WeekStartDate WeekEndDate
01/01/2015 04/01/2015
05/01/2015 11/01/2015
我曾尝试使用linq获得期望的结果,但我无法集中精力获得期望的输出,以下是我的尝试:
var dating = from d in dates
group d by new { d.Day, d.DayOfWeek,d.Date } into g
where g.Key.DayOfWeek == DayOfWeek.Monday || g.Key.DayOfWeek == DayOfWeek.Sunday
select g;
编辑:
我现在可以获得周组合,但它不完整,因为它错过了第一周到期的星期一检查,因为第一天可能不是星期一:
var dating = from d in dates
let NextWeekDate = d.Date.AddDays(6)
group d by new { d.Day, d.DayOfWeek, d.Date, NextWeekDate } into g
where g.Key.DayOfWeek == DayOfWeek.Monday
select new {
StartWeekDate = g.Key.Date,
EndWeekDate = g.Key.NextWeekDate
};
这应该能奏效。代码是自解释的;我使用了一个
元组作为一周的代表
var startDate = DateTime.Now.AddDays(-26);
var endDate = DateTime.Now.AddDays(1);
var weeks = new List<Tuple<DateTime, DateTime>>();
for (var date = startDate; date <= endDate; date = date.AddDays(1))
{
if (date == startDate)
{
// find the next Sunday
var start = (int)date.DayOfWeek;
var target = (int)DayOfWeek.Sunday;
if (target < start)
target += 7;
weeks.Add(Tuple.Create(date, date.AddDays(target - start)));
}
else if (date.DayOfWeek == DayOfWeek.Monday)
{
weeks.Add(Tuple.Create(date, date.AddDays(6)));
}
}
var startDate=DateTime.Now.AddDays(-26);
var endDate=DateTime.Now.AddDays(1);
var weeks=新列表();
对于(var date=startDate;date如果我正确理解您的问题,您有一个从一个月的可变点开始的日期集合,您需要一个星期开始和结束的列表。@Selman22是正确的,但您不能在1月1日的基础上再加6天来获得下一个星期日。
这与此类似,但将正确处理第一周的案例:
int firstDay = dates.Min(x => x).Day;
var dating = from d in dates
where d.DayOfWeek == DayOfWeek.Monday || d.Day == firstDay
select new
{
StartDate = d,
EndDate = d.AddDays(
Enumerable.Range(0, 7)
.First(n => d.AddDays(n).DayOfWeek == DayOfWeek.Sunday))
};
我在某处找到了这两种扩展方法,它们帮助我获得了所需的输出:
public static DateTime NextDayOfWeek(this DateTime dt, DayOfWeek dayOfWeek)
{
int offsetDays = dayOfWeek - dt.DayOfWeek;
return dt.AddDays(offsetDays > 0 ? offsetDays : offsetDays + 7).AtMidnight();
}
下一个星期五()
此返回从当前日期开始的一周的第二天,可通过以下方式使用:
这是本周的前一天:
上一周的日期()
此返回从当前日期开始的一周的前一天,可通过以下方式使用:
它可以像这样使用:
DateTime thisWeekMonday = DateTime.Now.PreviousDayOfWeek(DayOfWeek.Monday);
这是我的凌乱查询,经过重构后发现无需分组:
var dating = from d in dates
let PreviousDate = d.PreviousOfWeek(DayOfWeek.Monday)
let NextWeekDate = d.NextDayOfWeek(DayOfWeek.Sunday)
group d by new
{
d.Day,
d.DayOfWeek,
d.Date,
NextWeekDate
} into g
where g.Key.DayOfWeek == DayOfWeek.Monday
select new
{
StartWeekDate = g.Key.DayOfWeek != DayOfWeek.Monday ? g.Key.Date.PreviousOfWeek(DayOfWeek.Monday) : g.Key.Date,
EndWeekDate = g.Key.NextWeekDate
};
重构一:
var dating22 = (from d in dates
where d.DayOfWeek == DayOfWeek.Monday
select new
{
StartWeekDate = d.DayOfWeek != DayOfWeek.Monday ? d.Date.PreviousOfWeek(DayOfWeek.Monday) : d.Date,
EndWeekDate = d.NextDayOfWeek(DayOfWeek.Sunday)
}).Distinct();
如果我们希望从开始日期开始,然后:
DateTime startDate = new DateTime(2015, 1, 28);
DateTime endDate = new DateTime(2015, 2, 10);
var dates = startDate.Range(endDate);
var fromStartDateToEndDate = )from d in dates
where d.DayOfWeek == DayOfWeek.Monday
select new
{
StartWeekDate = d.Date,
EndWeekDate = d.Date.NextDayOfWeek(DayOfWeek.Sunday)
}).Distinct();
如果我们希望从开始日期的星期一开始,因为开始日期可以不是星期一,因此我们需要从星期一开始,如果:
var fromStartingWeekOfStartDateRefactored = (from d in dates
where d.DayOfWeek == DayOfWeek.Monday
select new
{
StartWeekDate = d.DayOfWeek != DayOfWeek.Monday ? d.Date.PreviousOfWeek(DayOfWeek.Monday) : d.Date,
EndWeekDate = d.NextDayOfWeek(DayOfWeek.Sunday)
}).Distinct();
//
///日期范围容器的自定义类。。。
///
[数据合同]
公共课周
{
[数据成员]
公共字符串范围{get;set;}
[数据成员]
公共字符串StartDate{get;set;}
[数据成员]
公共字符串EndDate{get;set;}
[数据成员]
公共整数周{get;set;}
[数据成员]
公共整数月{get;set;}
[数据成员]
公共整数年{get;set;}
}
///
///获取给定日期范围的周范围。。。。。
///
///
///
///
公共静态列表工作日(DateTime startDate、DateTime endDate)
{
DateTime startDateToCheck=startDate;
DateTime dateToCheck=开始日期;
DateTime dateRangeBegin=dateToCheck;
DateTime dateRangeEnd=endDate;
List weekRangeList=新列表();
WeekRange WeekRange=新的WeekRange();
当((startDateToCheck.Year如果我错了,请纠正我-您希望结果包含1.月的第一天2.所有星期日结束时间3.所有星期一开始时间。我对吗?@MotiAzu我想他希望每周的开始和结束日期都是一对。所以结果应该是这些对的列表。@Selman22我认为您是对的,有道理。@Selman22您得到了吗没错,我需要在给定日期范围内每周的开始日期和结束日期(21k)配对。你应该知道这个网站是如何工作的。把你的解决方案作为答案,不要编辑到问题中,也不要编辑[已解决]
添加到标题中。为您的答案添加一些解释。?上面的代码将以周的形式给出结果集,其中嵌入日期范围。希望有帮助……:)编辑您的答案,而不是添加注释,然后添加解释?
DateTime startDate = new DateTime(2015, 1, 28);
DateTime endDate = new DateTime(2015, 2, 10);
var dates = startDate.Range(endDate);
var fromStartDateToEndDate = )from d in dates
where d.DayOfWeek == DayOfWeek.Monday
select new
{
StartWeekDate = d.Date,
EndWeekDate = d.Date.NextDayOfWeek(DayOfWeek.Sunday)
}).Distinct();
var fromStartingWeekOfStartDateRefactored = (from d in dates
where d.DayOfWeek == DayOfWeek.Monday
select new
{
StartWeekDate = d.DayOfWeek != DayOfWeek.Monday ? d.Date.PreviousOfWeek(DayOfWeek.Monday) : d.Date,
EndWeekDate = d.NextDayOfWeek(DayOfWeek.Sunday)
}).Distinct();
/// <summary>
/// Customized class for the Date Range Container...
/// </summary>
[DataContract]
public class WeekRange
{
[DataMember]
public string Range { get; set; }
[DataMember]
public string StartDate { get; set; }
[DataMember]
public string EndDate { get; set; }
[DataMember]
public int Week { get; set; }
[DataMember]
public int Month { get; set; }
[DataMember]
public int Year { get; set; }
}
/// <summary>
/// Get the Week Range for the Given Date Range.....
/// </summary>
/// <param name="startDate"></param>
/// <param name="endDate"></param>
/// <returns></returns>
public static List<WeekRange> WeekDays(DateTime startDate, DateTime endDate)
{
DateTime startDateToCheck = startDate;
DateTime dateToCheck = startDate;
DateTime dateRangeBegin = dateToCheck;
DateTime dateRangeEnd = endDate;
List<WeekRange> weekRangeList = new List<WeekRange>();
WeekRange weekRange = new WeekRange();
while ((startDateToCheck.Year <= endDate.Year) && (startDateToCheck.Month <= endDate.Month) && dateToCheck <= endDate)
{
int week = 0;
while (startDateToCheck.Month == dateToCheck.Month && dateToCheck <= endDate)
{
week = week + 1;
dateRangeBegin = dateToCheck.AddDays(-(int)dateToCheck.DayOfWeek);
dateRangeEnd = dateToCheck.AddDays(6 - (int)dateToCheck.DayOfWeek);
if ((dateRangeBegin.Date < dateToCheck) && (dateRangeBegin.Date.Month != dateToCheck.Month))
{
dateRangeBegin = new DateTime(dateToCheck.Year, dateToCheck.Month, dateToCheck.Day);
}
if ((dateRangeEnd.Date > dateToCheck) && (dateRangeEnd.Date.Month != dateToCheck.Month))
{
DateTime dtTo = new DateTime(dateToCheck.Year, dateToCheck.Month, 1);
dtTo = dtTo.AddMonths(1);
dateRangeEnd = dtTo.AddDays(-(dtTo.Day));
}
if (dateRangeEnd.Date > endDate)
{
dateRangeEnd = new DateTime(dateRangeEnd.Year, dateRangeEnd.Month, endDate.Day);
}
weekRange = new WeekRange
{
StartDate = dateRangeBegin.ToShortDateString(),
EndDate = dateRangeEnd.ToShortDateString(),
Range = dateRangeBegin.Date.ToShortDateString() + '-' + dateRangeEnd.Date.ToShortDateString(),
Month = dateToCheck.Month,
Year = dateToCheck.Year,
Week = week
};
weekRangeList.Add(weekRange);
dateToCheck = dateRangeEnd.AddDays(1);
}
startDateToCheck = startDateToCheck.AddMonths(1);
}
return weekRangeList;
}