我有一个DayOfWeek枚举项目列表:var daysOfWeek = List<DayOfWeek>
此列表包含可变数量的DaysOfWeek项目,例如星期一,星期四,星期六。
我想根据List<DayOfWeek>
找到任何给定DateTime的下一个DateTime。
如果给定日期为星期三,则下一个应该返回的DateTime将为星期四。
如果给定的日期是星期四,那么下一个应该返回的DateTime将是星期六。
到目前为止,我一直在摆弄一些LINQ表达式,并使用Min()扩展方法尝试一些选项,但是没有可以共享的代码。我想知道我是否缺少一些真正的基本LINQ功能。
到目前为止,给我一些想法的SO-Topics包括this one和that one,但是我无法用他们的答案来解决我的问题。
答案 0 :(得分:2)
public static DateTime GetNextDateOrSomething(DateTime start, IEnumerable<DayOfWeek> weekdays)
{
if (!weekdays.Any()) throw new ArgumentException($"{nameof(weekdays)} cannot be empty.");
var increments = Enumerable.Range(1, 6);
var matchedIncrement = increments.FirstOrDefault(i => weekdays.Contains(start.AddDays(i).DayOfWeek));
return start.AddDays(matchedIncrement > 0 ? matchedIncrement : 7);
}
[DataTestMethod]
[DataRow("4/10/2019", "Wednesday,Thursday", "4/11/2019")]
[DataRow("4/10/2019", "Thursday", "4/11/2019")]
[DataRow("4/10/2019", "Monday,Tuesday", "4/15/2019")]
[DataRow("4/10/2019", "Tuesday", "4/16/2019")]
public void TestDateMethod(string start, string weekdays, string expected)
{
var startDate = DateTime.Parse(start);
var weekDaysList = weekdays.Split(',').Select(d => (DayOfWeek)Enum.Parse(typeof(DayOfWeek), d));
var expectedDate = DateTime.Parse(expected);
var result = GetNextDateOrSomething(startDate, weekDaysList);
Assert.AreEqual(expectedDate, result);
}
答案 1 :(得分:1)
您可以计算列表中明天与一周中第二天之间的(非负)距离,然后使用最小距离获取新日期:
var tomorrowDOW = startDate.AddDays(1).DayOfWeek;
var dist = daysOfWeek.Select(w => (w - tomorrowDOW + 14) % 7).Min();
var nextDate = startDate.AddDays(dist + 1);
答案 2 :(得分:1)
class Program
{
static DateTime NextDay(List<DayOfWeek> workingDays, DateTime dateTime)
{
var result = dateTime;
var dayOfWeek = (int)dateTime.DayOfWeek;
dayOfWeek++;
result = result.AddDays(1);
while (!workingDays.Any(x=> x == (DayOfWeek)dayOfWeek))
{
if (dayOfWeek > (int)workingDays.Last())
{
var delta = ((int)workingDays.First() + 7) - dayOfWeek;
dayOfWeek = (int)workingDays.First();
result = result.AddDays(delta);
}
else
{
dayOfWeek++;
result = result.AddDays(1);
}
}
return result;
}
static void Main(string[] args)
{
var workingDays = new List<DayOfWeek>()
{
DayOfWeek.Monday,
DayOfWeek.Thursday,
DayOfWeek.Saturday
};
workingDays.Sort();
var dayOfWeek = NextDay(workingDays, DateTime.Now);
Console.WriteLine(dayOfWeek.ToString());
dayOfWeek = NextDay(workingDays, DateTime.Now.AddDays(1));
Console.WriteLine(dayOfWeek.ToString());
dayOfWeek = NextDay(workingDays, DateTime.Now.AddDays(2));
Console.WriteLine(dayOfWeek.ToString());
dayOfWeek = NextDay(workingDays, DateTime.Now.AddDays(3));
Console.WriteLine(dayOfWeek.ToString());
Console.ReadLine();
}
}
}
答案 3 :(得分:1)
除了为该问题发布的出色答案之外,这是另一个对我有用的解决方案。我创建了以下私有方法,以根据给定的DateTime返回下一个DateTime,以获取有效的DayOfWeek项目列表:
private static DateTime NextDateTimeByDayOfWeek(DateTime target, List<DayOfWeek> validDaysOfWeek)
{
return Enumerable.Range(1, 7)
.Select(n => target.AddDays(n))
.First(date => validDaysOfWeek.Contains(date.DayOfWeek));
}