根据每周,每月的时间表查找下一个日期时间

时间:2013-12-16 08:51:04

标签: c# .net datetime .net-4.0

我试图根据每月或每周的时间表找到下一个预定日期。

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

2 个答案:

答案 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"