DateTime转移到下一个预定义的日期



说我有一个有效的安排日列表。类似:23、27、29

我想根据上述列表将给定的日期修改为下一个有效的日期。

如果您的给定日期是" 23/11/2013"下一个有效日期是" 27/11/2013"但是,如果您的给定日期是" 30/11/2013",则必须返回" 23/12/2013"如果给定的日期是" 30/12/2013",则必须返回" 23/01/2014"

我已经在SQL中完成了此操作,但是现在我将其转换为C#,这有点棘手。我正在尝试使用linq在sql相似性的列表上使用Linq进行操作,但是它会令人困惑。

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是一个工作表。

我认为您要寻找的是这样的东西(使用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 });

我认为您需要这样的东西:

    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日等)遇到一些问题...

以下不是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]);
    }

最新更新