C# 在你的描述中有不同的月份?如果可能的话,你能举个例子吗?如果你指定开始日期为1月15日,你应该包括1月吗?既然你指定了你想要的是那个月的第一天,也就是。哦,我们画的是一辆多么可爱的自行车:)@Lasse是的,你应该包括一月你的代码包括了下面的开始数据中的所
C# 在你的描述中有不同的月份?如果可能的话,你能举个例子吗?如果你指定开始日期为1月15日,你应该包括1月吗?既然你指定了你想要的是那个月的第一天,也就是。哦,我们画的是一辆多么可爱的自行车:)@Lasse是的,你应该包括一月你的代码包括了下面的开始数据中的所,c#,datetime,C#,Datetime,在你的描述中有不同的月份?如果可能的话,你能举个例子吗?如果你指定开始日期为1月15日,你应该包括1月吗?既然你指定了你想要的是那个月的第一天,也就是。哦,我们画的是一辆多么可爱的自行车:)@Lasse是的,你应该包括一月你的代码包括了下面的开始数据中的所有月份。例如,如果您的开始日期为2010年5月1日,那么您的代码将包括2010年1月1日、2010年2月1日、2010年3月1日和2010年4月1日。结束日期也一样。我稍微修改了您的代码,只提供开始数据和结束日期之间的日期。我给了你+1。是的,
在你的描述中有不同的月份?如果可能的话,你能举个例子吗?如果你指定开始日期为1月15日,你应该包括1月吗?既然你指定了你想要的是那个月的第一天,也就是。哦,我们画的是一辆多么可爱的自行车:)@Lasse是的,你应该包括一月你的代码包括了下面的开始数据中的所有月份。例如,如果您的开始日期为2010年5月1日,那么您的代码将包括2010年1月1日、2010年2月1日、2010年3月1日和2010年4月1日。结束日期也一样。我稍微修改了您的代码,只提供开始数据和结束日期之间的日期。我给了你+1。是的,我遗漏了这一点,但筛选日期以仅包括开始日期和结束日期之间的日期是一项琐碎的任务,我遗漏了问题的一些细节,但解决方案可以很容易地采用,你完全正确:-)如果数据集包含一年的间隔,这将不起作用。它只生产当年投入中有项目的年份的产出。考虑输入是空的情况,或者开始日期在列表中的第一个日期之前的一年发生的情况。是的,但是简单地,您可以使用<代码>枚举。范围(StaseDist.Eng.,EndoDist.ActhDistNo.Auth+ 1)< /Cord>生成年份,我只想呈现idea@Jani... 看起来不错,但你的代码是年-1。。。我猜应该是+1?如果endDate的day值低于startDate,这将错过最后一个月,即15。一月到一月一号。二月,你加上一个月,得到15。2月的,在结束日期之上。喜欢答案,但不幸的是,我不能使用4.0,因此无法访问tuple@mjmcloug所以使用一个
KeyValuePair
@mjmcloug-就像Jani建议的那样,你可以使用一个KeyValuePair(您还可以引入一个简单的MonthYear
类,该类包含月份和年份的两个int属性,但是如果您这样做了,请记住执行equals
和GetHashCode
!)什么是“AllMonths”?并且不是所有月份都必须返回日期时间集合才能符合GetMissingMonths方法的返回类型吗?因此不会。除了因为只选择月份而不起作用之外?哎哟,重命名了一个方法,但没有修复调用。修复了。@Iain。感谢您指出。我修复了它。请检查这个。如果几乎是这样,有问题吗不可读,因此更难维护。虽然只有一行,这很酷。@blesh。我同意这很难阅读,但它显示了LINQ的威力。哈哈……没关系,它并不比选择的答案更难看。讽刺的是,LINQ只是一种以更功能化的方式编写循环的奇特方式。我不确定它是否值得以维护性为代价加以利用lity。和我的方式没什么不同……不过我喜欢。复杂的linq有时会使事情难以维护。请解释一下,这样每个人都可以从你的发现中学习
private List<DateTime> GetUnincludedMonths(DateTime startDate, DateTime endDate,
IEnumerable<DateTime> dates)
{
var allMonths = new HashSet<Tuple<int, int>>(); //month, year
DateTime date = startDate;
while (date <= endDate)
{
allMonths.Add(Tuple.Create(date.Month, date.Year));
date = date.AddMonths(1);
}
allMonths.Add(Tuple.Create(endDate.Month, endDate.Year));
allMonths.ExceptWith(dates.Select(dt => Tuple.Create(dt.Month, dt.Year)));
return allMonths.Select(t => new DateTime(t.Item2, t.Item1, 1)).ToList();
}
var list = new List<DateTime>
{
new DateTime(1231223423433132),
new DateTime(13223123132),
new DateTime(12333123132),
new DateTime(123345123132),
DateTime.Now,
new DateTime(5634534553)
};
var allYearMonthes = list.Select(o =>
Eumerable.Range(1, 12)
.Select(q => new { o.Year, Month = q }))
.SelectMany(o => o);
var enumerable = allYearMonthes.Except(list.Select(o => new { o.Year, o.Month }));
var dateTimes = enumerable.Select(o => new DateTime(o.Year, o.Month, 1));
DateTime StartDate = DateTime.Now, EndDate = DateTime.Now.AddYears(5).AddMonths(2);
var allYearMonthes = Enumerable.Range(StartDate.Year, EndDate.Year - StartDate.Year -1)
.Select(o => Enumerable.Range(1, 12)
.Select(q => new { Year = o, Month = q }))
.SelectMany(o => o);
var enumerable = allYearMonthes.Except(list.Select(o => new { o.Year, o.Month }));
var dateTimes = enumerable.Select(o => new DateTime(o.Year, o.Month, 1));
public IList<DateTime> GetMissingMonths(IList<DateTime> currentList, DateTime startDate, DateTime endDate)
{
// Create a list for the missing months
IList<DateTime> missingList = new List<DateTime>();
// Select a startdate
DateTime testingDate = startDate;
// Begin by the month of startDate and ends with the month of endDate
// month of startDate and endDate included
while(testingDate <= endDate)
{
if (currentList.Count(m => m.Month == testingDate.Month && m.Year == testingDate.Year) == 0)
{
missingList.Add(new DateTime(testingDate.Year, testingDate.Month, 1));
}
testingDate = testingDate.AddMonths(1);
}
return missingList;
}
static IEnumerable<DateTime> GetMissingMonths(IEnumerable<DateTime> currentDates, DateTime startDate, DateTime endDate)
{
var yearMonths = new HashSet<Tuple<int, int>>(currentDates.Select(d => Tuple.Create(d.Year, d.Month)));
DateTime current = new DateTime(startDate.Year, startDate.Month, 1);
if (current < startDate)
current = current.AddMonths(1);
while (current <= endDate)
{
if (!yearMonths.Contains(Tuple.Create(current.Year, current.Month)))
{
yield return current;
}
current = current.AddMonths(1);
}
}
static IEnumerable<DateTime> GetMissingMonths(IEnumerable<DateTime> currentDates, DateTime startDate, DateTime endDate)
{
var yearMonths = MakeHashSet(currentDates.Select(d => new { d.Year, d.Month }));
DateTime current = new DateTime(startDate.Year, startDate.Month, 1);
if (current < startDate)
current = current.AddMonths(1);
while (current <= endDate)
{
if (!yearMonths.Contains(new { current.Year, current.Month }))
{
yield return current;
}
current = current.AddMonths(1);
}
}
static HashSet<T> MakeHashSet<T>(IEnumerable<T> source)
{
return new HashSet<T>(source);
}
void Main()
{
var dates = new List<DateTime>
{
new DateTime(2011, 1, 1),
new DateTime(2011, 3, 5),
new DateTime(2011, 7, 28),
};
var startDate = new DateTime(2011, 1, 1);
var endDate = new DateTime(2012, 12, 31);
var existingMonths =
(from dt in dates
select dt.Year * 12 + dt.Month - 1).Distinct().ToArray();
var missingMonths =
from ym in Enumerable.Range(
startDate.Year * 12 + startDate.Month - 1,
(endDate.Year * 12 + endDate.Month) - (startDate.Year * 12 + startDate.Month) + 1)
where !existingMonths.Contains(ym)
select new DateTime(ym / 12, ym % 12 + 1, 1);
missingMonths.Dump();
}
static void Main(string[] args)
{
var days = (new string[] { "3/23/2000", "7/3/2004", "1/3/2004", "3/1/2011" })
.Select(a => Convert.ToDateTime(a));
days = days.Select(a => a.AddDays(1 - (a.Day))).Distinct();
days = days.OrderBy(a => a);
var missingMonths = GetMissingMonths(days).ToList();
}
private static IEnumerable<DateTime> GetMissingMonths(IEnumerable<DateTime> days)
{
DateTime previous = days.First();
foreach (var current in days.Skip(1))
{
int months = (current.Month - previous.Month) +
12 * (current.Year - previous.Year);
for (int i = 1; i < months; i++)
{
yield return previous.AddMonths(i);
}
previous = current;
}
}
public IEnumerable<DateTime> GetMissingMonths(
DateTime startDate,
DateTime endDate,
IEnumerable<DateTime> source)
{
IEnumerable<DateTime> sourceMonths =
source.Select(x => new DateTime(x.Year, x.Month, 1))
.ToList()
.Distinct();
return MonthsBetweenInclusive(startDate, endDate).Except(sourceMonths);
}
public IEnumerable<DateTime> MonthsBetweenInclusive(
DateTime startDate,
DateTime endDate)
{
DateTime currentMonth = new DateTime(startDate.Year, startDate.Month, 1);
DateTime endMonth = new DateTime(endDate.Year, endDate.Month, 1);
while(currentMonth <= endMonth)
{
yield return currentMonth;
currentMonth = currentMonth.AddMonths(1);
}
}
void Main()
{
var list = new List<DateTime>
{
new DateTime(2005, 10, 11),
new DateTime(2009, 3, 4),
new DateTime(2010, 5, 8),
new DateTime(2010, 8, 10),
DateTime.Now,
new DateTime(2010, 4, 8)
};
var result= Enumerable.Range(list.Min (l => l.Year), list.Max (l => l.Year) - list.Min (l => l.Year)).
SelectMany (e => Enumerable.Range(1, 12).Select (en => new DateTime(e, en, 1))).
Except(list.Select(o => new DateTime(o.Year, o.Month, 1))).
Where (o => o.Date > list.Min (l => l.Date) && o.Date < list.Max (l => new DateTime(l.Year, l.Month, 1)));
}
IEnumerable<DateTime> FindMissingMonths(DateTime startDate, DateTime endDate, IEnumerable<DateTime> inputs)
{
var allMonths = new List<DateTime>();
for (DateTime d = startDate; d < endDate; d = d.AddMonths(1))
{
allMonths.Add(new DateTime(d.Year, d.Month, 1));
}
var usedMonths = (from d in inputs
select new DateTime(d.Year, d.Month, 1)).Distinct();
return allMonths.Except(usedMonths);
}