假设我有一个有效的安排日期列表。像:23,27,29
我想根据上面的列表将给定日期修改为下一个有效的日期。
如果您的指定日期是“23/11/2013”,则下一个有效日期为“27/11/2013” 但如果您的指定日期是“30/11/2013”,则必须返回“2013年12月23日” 如果给定的日期是“30/12/2013”,则必须返回“23/01/2014”
我已经在SQL中完成了这项工作,但现在我正在将它转换为C#,这有点棘手。 我试图在列表中使用LINQ来实现SQL相似性,但它会让人感到困惑。
SQL语句是(是的,我知道它不会很快):
SELECT TOP 1 @DATE = ISNULL(DateAdd(yy, YEAR(@DATE)-1900, DateAdd(m, (MONTH(@DATE)+CASE WHEN DATEPART(day,@DATE)>[DAY] THEN 1 ELSE 0 END) - 1, [DAY] - 1)),@DATE)
FROM @DAYS WHERE DateAdd(yy, YEAR(@DATE)-1900, DateAdd(m, (MONTH(@DATE)+CASE WHEN DATEPART(day,@DATE)>[DAY] THEN 1 ELSE 0 END) - 1, [DAY] - 1))>=@DATE
ORDER BY [DAY]
@DAYS是一张工作台。
答案 0 :(得分:2)
我认为你需要这样的东西:
public static DateTime GetNextValidDate(DateTime date)
{
var validDays = new List<short> { 23, 27, 29 };
var nextDay = validDays.FirstOrDefault(n => n >= date.Day);
if (nextDay != default(int))
{
// The next valid day is in the current month
return date.AddDays(nextDay - date.Day);
}
// The next valid day is next month
nextDay = validDays.Min();
return new DateTime(date.Year, date.Month, nextDay, date.Hour, date.Minute, date.Second).AddMonths(1);
}
我已经使用一些值测试了这段代码,它运行正常:
Console.WriteLine(GetNextValidDate(new DateTime(2014, 1, 20)));
Console.WriteLine(GetNextValidDate(new DateTime(2014, 1, 24)));
Console.WriteLine(GetNextValidDate(new DateTime(2014, 1, 30)));
有一个限制:如果第一个有效日期最多为28,那么您可能会遇到2月份的问题(以及4月份的31个问题......)
答案 1 :(得分:2)
我认为您正在寻找的是这样的(使用LINQ):
public static DateTime NextDate(DateTime seed, int[] days)
{
if (Enumerable.Range(1, 31).Intersect(days).Any()) //Check to stop a very long running lookup!
{
return Enumerable.Range(0, int.MaxValue)
.Select(i => seed.AddDays(i))
.First(d => days.Contains(d.Day));
}
return seed;
}
用法:
var nextDate = NextDate(DateTime.Now, new[] { 23, 27, 29 });
答案 2 :(得分:1)
以下不是LINQ,但应该有效(也随着年份增加):
private IList<int> days = new[] {23, 27, 29};
public DateTime Next(DateTime current)
{
int i = days.IndexOf(current.Day);
if(i<0) throw new ArgumentException("Wrong date");
if(i<days.Count-1) return new DateTime(current.Year, current.Month, days[i+1]);
current = current.AddMonths(1);
return new DateTime(current.Year, current.Month, days[0]);
}