从对象中获取日期列表
Get List of dates from object
我读了几个线程,但不确定如何从一个范围中获取最早和最晚的日期。
数据示例(为简洁起见跳过了大多数列)
CustID StartDate EndDate
1 01/01/2015 01/01/2015
2 03/01/2015 03/01/2015
3 03/01/2015 05/01/2015
4 03/01/2015 10/01/2015
UI 允许用户select 来自日历控件的日期。然后它应该得到上述范围内的所有日期,所以如果用户 selects
02/01/2015 - 没有 returned 因为没有 startDate
或 EndDate
匹配此 date/range
如果他们 select 01/01/2015 那么我希望获得以下日期
01/01/2015
03/01/2015
04/01/2015
05/01/2015
.... to 10/01/2015
注意日期 02/01/2015 不包括在内。
如果用户 selects 03/01/2015 那么它将 return 所有日期直到 10/01/2015。
为了实现这个我写了代码
public List<DateTime> GetDates()
{
IEnumerable<Customers> Dates = dc.Customers.Where(d => d.StartDate.Value >= DateTime.Now );
DateTime FromDate = Dates.Where(f => f.StartDate.HasValue).Min(f => f.StartDate).Value;
DateTime ToDate = Dates.Where(t => t.EndDate.HasValue).Max(f => f.EndDate).Value;
IEnumerable<DateTime> AllDates = Enumerable.Range(0, int.MaxValue)
.Select(x => FromDate.Date.AddDays(x))
.TakeWhile(x => x <= ToDate.Date);
return AllDates.ToList();
}
但它不是 return我预期的日期。使用此代码,如果我 select 01/01/2015,它 return 是所有日期?我哪里错了?
我的猜测是他正试图用其他客户已经 select 编辑过的日期填充日历控件,因此用户不能 select 它们,但他正试图减少项目的数量 returned 到一个较小的集合。当然,示例数据将是错误的,因为它已经有重叠的日期,所以...
第一关:
public List<DateTime> GetDates()
{
IEnumerable<Customers> Dates = dc.Customers
.Where(d => d.StartDate.Value >= DateTime.Now);
var FromDate = Dates.Where(f => f.StartDate.HasValue)
.Min(f => f.StartDate).Value;
var ToDate = Dates.Where(t => t.EndDate.HasValue)
.Max(f => f.EndDate).Value;
IEnumerable<DateTime> AllDates = Enumerable.Range(0, int.MaxValue)
.Select(x => FromDate.Date.AddDays(x))
.TakeWhile(x => x <= ToDate.Date)
.Where(x=>dc.Customers.Any(c=>x>=c.StartDate && x<=c.EndDate));
return AllDates.ToList();
}
这是一个更好的解决方案,但是 return 所有范围内的所有日期,通过在需要的地方添加 where 子句进一步减少。把它放在 .ToList
之前,如果你真的想排除所有没有开始日期 >= 你的 selection 的范围,或者如果你真的想包括它们,把它放在最后,但不是 return <您的 selection 的部分(更有可能)。
public List<DateTime> GetDates()
{
return db.Customers
.ToList()
.Select(pair =>
Enumerable.Range(0,(int)(pair.EndDate - pair.StartDate).TotalDays+1)
.Select(days => pair.StartDate.AddDays(days)))
.SelectMany(x=>x)
.Distinct();
}
奖金:
/* DateTime extension for ranges of dates */
public static class DateTimeExtensions
{
public static IEnumerable<DateTime> EnumerableTo(this DateTime self, DateTime toDate)
{
for(var d=self;d<=toDate;d=d.Date.AddDays(1))
yield return d;
}
}
void Main()
{
/* Your example data */
var Customers=new [] {
new { id=1,StartDate=new DateTime(2015,1,1),EndDate=new DateTime(2015,1,1)},
new { id=2,StartDate=new DateTime(2015,1,3),EndDate=new DateTime(2015,1,3)},
new { id=3,StartDate=new DateTime(2015,1,3),EndDate=new DateTime(2015,1,5)},
new { id=4,StartDate=new DateTime(2015,1,3),EndDate=new DateTime(2015,1,10)},
};
/* The query */
var results=Customers
.Select(pair => pair.StartDate.EnumerableTo(pair.EndDate))
.SelectMany(x=>x)
.Distinct();
results.Dump();
}
如果您想要的是所有客户的开始日期和结束日期的联合,其中开始日期大于用户选择的日期,那么为什么不像
return (from costumer in dc.Customers select costumer.startdate
where costumer.startdate > UserSelectedDate)
.Union
(from costumer in dc.Customers select costumer.enddate
where costumer.startdate > UserSelectedDate)
.Distinct()
如果您想要的是用户选择的所有开始日期和结束日期都在该范围内,那么您会做
return (from costumer in dc.Customers select costumer.startdate
where costumer.startdate <= UserSelectedDate and
UserSelectedDate <= costumer.enddate)
.Union
(from costumer in dc.Customers select costumer.enddate
where costumer.startdate <= UserSelectedDate and
UserSelectedDate <= costumer.enddate)
.Distinct()
我读了几个线程,但不确定如何从一个范围中获取最早和最晚的日期。
数据示例(为简洁起见跳过了大多数列)
CustID StartDate EndDate
1 01/01/2015 01/01/2015
2 03/01/2015 03/01/2015
3 03/01/2015 05/01/2015
4 03/01/2015 10/01/2015
UI 允许用户select 来自日历控件的日期。然后它应该得到上述范围内的所有日期,所以如果用户 selects
02/01/2015 - 没有 returned 因为没有 startDate
或 EndDate
匹配此 date/range
如果他们 select 01/01/2015 那么我希望获得以下日期
01/01/2015
03/01/2015
04/01/2015
05/01/2015
.... to 10/01/2015
注意日期 02/01/2015 不包括在内。
如果用户 selects 03/01/2015 那么它将 return 所有日期直到 10/01/2015。
为了实现这个我写了代码
public List<DateTime> GetDates()
{
IEnumerable<Customers> Dates = dc.Customers.Where(d => d.StartDate.Value >= DateTime.Now );
DateTime FromDate = Dates.Where(f => f.StartDate.HasValue).Min(f => f.StartDate).Value;
DateTime ToDate = Dates.Where(t => t.EndDate.HasValue).Max(f => f.EndDate).Value;
IEnumerable<DateTime> AllDates = Enumerable.Range(0, int.MaxValue)
.Select(x => FromDate.Date.AddDays(x))
.TakeWhile(x => x <= ToDate.Date);
return AllDates.ToList();
}
但它不是 return我预期的日期。使用此代码,如果我 select 01/01/2015,它 return 是所有日期?我哪里错了?
我的猜测是他正试图用其他客户已经 select 编辑过的日期填充日历控件,因此用户不能 select 它们,但他正试图减少项目的数量 returned 到一个较小的集合。当然,示例数据将是错误的,因为它已经有重叠的日期,所以...
第一关:
public List<DateTime> GetDates()
{
IEnumerable<Customers> Dates = dc.Customers
.Where(d => d.StartDate.Value >= DateTime.Now);
var FromDate = Dates.Where(f => f.StartDate.HasValue)
.Min(f => f.StartDate).Value;
var ToDate = Dates.Where(t => t.EndDate.HasValue)
.Max(f => f.EndDate).Value;
IEnumerable<DateTime> AllDates = Enumerable.Range(0, int.MaxValue)
.Select(x => FromDate.Date.AddDays(x))
.TakeWhile(x => x <= ToDate.Date)
.Where(x=>dc.Customers.Any(c=>x>=c.StartDate && x<=c.EndDate));
return AllDates.ToList();
}
这是一个更好的解决方案,但是 return 所有范围内的所有日期,通过在需要的地方添加 where 子句进一步减少。把它放在 .ToList
之前,如果你真的想排除所有没有开始日期 >= 你的 selection 的范围,或者如果你真的想包括它们,把它放在最后,但不是 return <您的 selection 的部分(更有可能)。
public List<DateTime> GetDates()
{
return db.Customers
.ToList()
.Select(pair =>
Enumerable.Range(0,(int)(pair.EndDate - pair.StartDate).TotalDays+1)
.Select(days => pair.StartDate.AddDays(days)))
.SelectMany(x=>x)
.Distinct();
}
奖金:
/* DateTime extension for ranges of dates */
public static class DateTimeExtensions
{
public static IEnumerable<DateTime> EnumerableTo(this DateTime self, DateTime toDate)
{
for(var d=self;d<=toDate;d=d.Date.AddDays(1))
yield return d;
}
}
void Main()
{
/* Your example data */
var Customers=new [] {
new { id=1,StartDate=new DateTime(2015,1,1),EndDate=new DateTime(2015,1,1)},
new { id=2,StartDate=new DateTime(2015,1,3),EndDate=new DateTime(2015,1,3)},
new { id=3,StartDate=new DateTime(2015,1,3),EndDate=new DateTime(2015,1,5)},
new { id=4,StartDate=new DateTime(2015,1,3),EndDate=new DateTime(2015,1,10)},
};
/* The query */
var results=Customers
.Select(pair => pair.StartDate.EnumerableTo(pair.EndDate))
.SelectMany(x=>x)
.Distinct();
results.Dump();
}
如果您想要的是所有客户的开始日期和结束日期的联合,其中开始日期大于用户选择的日期,那么为什么不像
return (from costumer in dc.Customers select costumer.startdate
where costumer.startdate > UserSelectedDate)
.Union
(from costumer in dc.Customers select costumer.enddate
where costumer.startdate > UserSelectedDate)
.Distinct()
如果您想要的是用户选择的所有开始日期和结束日期都在该范围内,那么您会做
return (from costumer in dc.Customers select costumer.startdate
where costumer.startdate <= UserSelectedDate and
UserSelectedDate <= costumer.enddate)
.Union
(from costumer in dc.Customers select costumer.enddate
where costumer.startdate <= UserSelectedDate and
UserSelectedDate <= costumer.enddate)
.Distinct()