2013-12-16 77 views
1

我正在尝试根据每月或每周时间表查找下一个预定日期。根据每周,每月时间表查找下一个日期时间

例如

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将基于这些数据?

例如12/16/2013每周运行1 | 3 | 5,下一个计划将是12/18/2013

回答

4

您可能会尝试使用Enum System.DayOfWeek。这恰好是从DateTime.DayOfWeek返回的类型,您可以使用它来查找您的开始日期的周日。

从这一点,你应该能够找到使用DateTime.AddDays(x)DateTime.AddMonths(X)(有一些简单的加减法找到x时采取当前工作日或日期在内),第二天(S)。

提示:如果您在解决此问题时遇到问题,请确保您首先确切知道需要。如果有必要,在尝试编写代码之前,用简单的英语写下您的要求。一旦你有明确定义了问题,解决它应该不会太难......

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; 
} 

现在它很简单,重新adable:

DateTime? nextScheduled = GetNextScheduledDate(DateTime.Today); 
// nextScheduled.Value.ToString("d", CultureInfo.InvariantCulture): "12/16/2013" 
相关问题