检查所选日期是否在预定义假期的三天内

时间:2017-11-11 06:20:43

标签: c# datetime c#-4.0

这适用于工作中的程序。我现在无法访问代码,但我真的想弄清楚这一点,所以我在家写了一个快速程序,模仿我的工作项目。

我需要知道该日期是否在“假期”的3个工作日内。如果是,则所选日期必须加1以跳过假日。例如:

如果“01/19/2018”上有假期且用户选择“01/16/2018”,则程序必须跳过第19个,然后将结束日期设置为“01/20/2018”。现在,如果我执行纯if / then语句,我可以按预期工作,但问题就变成:“如果01/19/2018和01/20/2018都是假期会怎么样?”这就是我被困住的地方。

在工作中,我正在使用一个已经有“MM / dd / yyyy”格式的日期列的SQL表(因此这些日期是我正在检查的列表源。)用户打开一个日历,选择一个日期。 我实际上是在解析一个XML文件,该文件是由另一个实际触及数据库的方法创建的,然后使用XElement进行迭代,将所有这些日期放在字符串列表中。

这是我的伪工作程序中的代码:

        private void button1_Click(object sender, EventArgs e)
        {
        DateTime dt = DateTime.Now;
        txtLog.Text = dt.ToString("MM/dd/yy") + Environment.NewLine;
        List<string> allexemptdays = new List<string>();
        string[] days = { "11/19/2018", "11/20/2018" };

        foreach (string a in days)
        {
            allexemptdays.Add(a);
        }

        foreach (string a in allexemptdays)
        {
            ToLog(a);
        }

        DateTime eq = DateTime.Parse(txtDate.Text);
        string thefrustrationisreal = eq.ToString("MM/dd/yy");

        if (Math.Abs(DateTime.Now.Subtract(eq).Days) <= 3)
        {
            MessageBox.Show("Date exemption found.");
        }

    }

    private void ToLog(string a)
    {
        txtLog.Text += ("Array value to list: " + a + Environment.NewLine);
    }

    private void monthCalendar1_DateSelected(object sender, DateRangeEventArgs e)
    {
        txtDate.Text = monthCalendar1.SelectionStart.ToString("MM/dd/yy");
    }

显然我明白“DateTime.Now”并不能反映我的要求,但我只是在玩DateTime课程。

简而言之:我正在创建一个包含日期的数组(类似于我的真实程序) 迭代它们,将它们添加到列表中。现在我需要检查所选日期是否在预定义日期的3天内从我的sql表返回的值开始。

如果找到日期,请将截止日期提前一天;但是,如果找到连续的假期,则完全跳过这两个日期。我可以逐个进行此操作(使用if / then)但如果两个假期相互背靠背则不能正常工作。

作为旁注,我希望能够判断所选日期是否在3天内并且移动到另一个月,但我想我可以使用DateTime来处理,检查一个月内的天数并在需要时递增(或者我确定DateTime实际上可以为我做到这一点。)虽然此时我并不太担心这个问题。

我确实接受了Mike的答案,因为它确实按预期工作,但是!我现在有一个不同的问题

现在,“days.count()”在用户选择假日之后的日期后会保留一个持久数字。示例:选择2017年1月21日作为截止日期返回“2017年1月26日”,因为它仍然将20日和21日视为受范围影响的假期,此时应将截止日期设置为“2017年1月24日”

我玩过提供的代码;我找不到一个好方法来解决它。我正在思考以下几点:

If(selectedDate.AddDays(3) >= holidaydate)然后在日期时间列表中检查另一天,但是我仍然会比那更复杂(我想。)

我将对此帖做最后一个条目(我现在正在考虑解决这个问题):

我选择马特的答案确实有效,我很感激他的帮助。问题是,.Count()永远不会重置,所以如果你超过假日日期,它总是保持跳过的日期(所以不会在所选日期之前3天,它会去(3) +计算的总天数))

如果其他人遇到这样的情况,这就是我最终要做的事情:

下载“WorkingDaysManagement”参考,说明来自:

https://github.com/Opturne/WorkingDaysManagement

我最终使用的代码是:

        private void button1_Click(object sender, EventArgs e)
    {
        txtLog.Text = null;
        DateTime dt = DateTime.Now;
        var sd = (DateTime.Parse(txtDate.Text));

        Console.WriteLine(sd.ToShortDateString());
        var listHolidays = new List<DateTime>
        {
            new DateTime(2017, 12, 24),
            new DateTime(2017, 12, 25)
        };

        var listWeekEnd = new List<DayOfWeek>
        {
            DayOfWeek.Saturday,
            DayOfWeek.Sunday
        };

        var helper = new WorkingDayHelper(listHolidays,listWeekEnd);
        foreach(DateTime s in helper.GetSpanDates(sd,3))
        {
            Console.WriteLine("Current iteration date: "+s.ToShortDateString());
        }
        var nextworkday = (helper.GetSpanDates(sd, 3).Last().ToString());
        txtLog.Text += ("Next working day available: " + nextworkday + Environment.NewLine);
        if(helper.IsWorkingDay(sd)==true)
        {
            txtLog.Text += ("It is a working a day." + Environment.NewLine);
        }
        else
        {
            txtLog.Text += ("NOT a working day!" + Environment.NewLine);
        }

        txtEndDate.Text = nextworkday;
    }

该插件的作者非常慷慨,也将他的作品置于麻省理工学院的许可证之下。

1 个答案:

答案 0 :(得分:2)

假设您已将数据库中的所有日期字符串解析为List<DateTime>holidays。然后你可以做类似

的事情
// Parsed holidays in a list, we will use LINQ against it.
var holidays = new List<DateTime> {
    new DateTime(2017, 1, 19),
    new DateTime(2017, 1, 20),
};
// Selected Date. In your case it would be: DateTime.Parse(txtDate.Text);
var selectedDate = new DateTime(2017, 1, 16);

// Count how many holidays there are within 3 days from the selcted date.
var count = holidays.Count(holiday => holiday - selectedDate <= TimeSpan.FromDays(3));

// Then add the count and 3 to the selected date
var closingDate = selectedDate.AddDays(count + 3);

// Now we have to make sure the closing date is not a holiday.
if (count > 0)
{
    int skipDays = 0;
    while (holidays.Any(holiday => holiday == closingDate.AddDays(skipDays)))
    {
        // holidays list contains the date. Skip it.
        skipDays++;
    }

    closingDate = closingDate.AddDays(skipDays);
}