我试图根据每月或每周的时间表找到下一个预定日期。
e.g。
ScheduleMode: M or W for monthly or weekly
Monthly:
1|15|29 will run on the 1st, 15th and 29th of every month
Weekly:
1|3|5 will run every Monday, Wednesday and Friday
如何根据这些数据确定下一个Datetime的内容?
e.g。 12/16/2013每周运行1 | 3 | 5,下一个时间表将是12/18/2013
答案 0 :(得分:4)
您可以尝试使用枚举System.DayOfWeek
。这恰好是DateTime.DayOfWeek
的返回类型,您可以使用它来查找开始日期的工作日。
由此,您应该能够使用DateTime.AddDays(x)
或DateTime.AddMonths(X)
找到第二天(通过一些简单的加法和减法,在查找{{{{{{ 1}})。
提示:如果您在解决此问题时遇到问题,请务必先了解您所需的内容。如有必要,在尝试编写代码之前,请用简单的英语写下您的要求。一旦你明确地定义了问题,解决它实际上应该不会太难......
答案 1 :(得分:2)
我会使用创建自定义类Schedule
来封装计算和数据。然后,您可以填充用作数据源的List<Schedule>
(或不同的集合类型/数据库)。
这是一个可能的实现:
public class Schedule
{
public enum Type
{
Monthly,
Weekly
}
public Schedule(DayOfWeek weekDay)
{
this.ScheduleType = Type.Weekly;
this.WeekDay = weekDay;
}
public Schedule(int monthDay)
{
if (monthDay < 1 || monthDay > 31)
throw new ArgumentException("Invalid day");
this.ScheduleType = Type.Monthly;
this.MonthDay = monthDay;
}
public Type ScheduleType { get; set; }
public int MonthDay { get; set; }
public DayOfWeek WeekDay { get; set; }
public String Comment { get; set; }
}
以下是列表以及样本数据的初始化:
private List<Schedule> _AllSchedules;
public List<Schedule> AllSchedules
{
get
{
if (_AllSchedules == null)
{
_AllSchedules = new List<Schedule>();
Schedule s1 = new Schedule(1);
Schedule s2 = new Schedule(15);
Schedule s3 = new Schedule(29);
Schedule s4 = new Schedule(DayOfWeek.Monday);
Schedule s5 = new Schedule(DayOfWeek.Wednesday);
Schedule s6 = new Schedule(DayOfWeek.Friday);
_AllSchedules.AddRange(new[] { s1, s2, s3, s4, s5, s6 });
}
return _AllSchedules;
}
}
这是一个可能的(未经过全面测试的)计算实现,可以给你一个想法:
public DateTime? GetNextScheduledDate(DateTime from)
{
var nextMonthDay = AllSchedules
.Where(s => s.ScheduleType == Schedule.Type.Monthly && s.MonthDay >= from.Day)
.OrderBy(s => s.MonthDay)
.DefaultIfEmpty(AllSchedules
.Where(s => s.ScheduleType == Schedule.Type.Monthly && s.MonthDay < from.Day)
.OrderByDescending(s => s.MonthDay)
.FirstOrDefault())
.FirstOrDefault();
var nextWeekDay = AllSchedules
.Where(s => s.ScheduleType == Schedule.Type.Weekly)
.Select(s => new { Schedule = s, Diff = ((int)s.WeekDay- (int)from.DayOfWeek) })
.OrderBy(x => x.Diff >= 0)
.ThenBy(x => Math.Abs(x.Diff))
.FirstOrDefault();
DateTime? nextMonthDate = null;
DateTime? nextWeekDate = null;
if (nextMonthDay != null)
{
int diff = nextMonthDay.MonthDay - from.Day;
if (diff < 0)
{
// next month
nextMonthDate = from.AddMonths(1).AddDays(diff);
}
else
{
// this month
nextMonthDate = from.AddDays(diff);
}
}
if (nextWeekDay != null)
{
nextWeekDate = from.AddDays(nextWeekDay.Diff < 0 ? 7 - Math.Abs(nextWeekDay.Diff) : nextWeekDay.Diff);
}
if (!nextMonthDate.HasValue && !nextWeekDate.HasValue)
return null;
else
return nextMonthDate < nextWeekDate ? nextMonthDate : nextWeekDate;
}
现在它简单易读:
DateTime? nextScheduled = GetNextScheduledDate(DateTime.Today);
// nextScheduled.Value.ToString("d", CultureInfo.InvariantCulture): "12/16/2013"