Say that I have a list of valid scheduling days. Something like: 23, 27, 29
I want to modify a given date to it's next valid day-month based on the above list.
If your given date was "23/11/2013" the next valid date would be "27/11/2013" But If your given date was "30/11/2013" it has to return "23/12/2013" And if the given date is "30/12/2013" it has to return "23/01/2014"
I've done that in SQL, but now I'm translating it to C# and it's a bit tricky. I'm trying to do it using LINQ over the list for SQL similarity, but it gets confusing.
The SQL statement was (yes, i know it doesn't swift year):
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 was a working table.
I think what you're looking for is something like this (using 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;
}
Usage:
var nextDate = NextDate(DateTime.Now, new[] { 23, 27, 29 });
I think you need something like this:
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);
}
I've tested this code with a few values and it works fine :
Console.WriteLine(GetNextValidDate(new DateTime(2014, 1, 20)));
Console.WriteLine(GetNextValidDate(new DateTime(2014, 1, 24)));
Console.WriteLine(GetNextValidDate(new DateTime(2014, 1, 30)));
There is one limitation: if the first valid day is up to 28, you can have some issues with February (and April with 31 etc...)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With