字典中不存在给定的DateTime键

时间:2013-09-30 21:49:51

标签: c# dictionary key containskey

我是C#和编程的初学者。我正在尝试计算一些DateTime个变量。第一个称为dDate,第二个dDate1dDate的前一天),第三个dDate2dDate的第二天,即前一天dDate1),第四个dDate3dDate的第三天,即dDate1的前一天和{{1}的前一天})。他们一定不是假期或周末!

我已将所有假期和周末存储在名为dDate2的字典中。密钥nd<DateTime, string>包含从DateTime2011-01-01的一系列日期,一天一步,值2013-01-01stringTR ,一个字符串变量,但不是布尔值。如果是周末或假日,则字符串为NT,否则为NT

我想要做的是TR是周末或假日,减去一天。例如,dDate dDate是假日,将2012-01-02更改为dDate,因为它是周末(星期日),请将其更改为2012-01-01,再过周末,将2011-12-31更改为dDate。与2011-12-30dDate1dDate2相同。

这里的问题是我的代码适用于dDate3。但它给出了一个错误:

  

字典中没有给定的密钥

当我为dDatedDate1dDate2做同样的事情时。代码如下:

dDate3

1 个答案:

答案 0 :(得分:1)

根据您的描述,您似乎要做的是在给定日期找到第一个非假日日期。

使用字典并存储每个可能的日期不是正确的解决方案。

就我个人而言,我认为HashSet<DateTime>加上一点数学将是最好的解决方案。事实上我很无聊所以我写了

static class HolidayTester
{
    private static HashSet<DateTime> fixedHolidays = new HashSet<DateTime>(new DayOnlyComparer())
        {
            new DateTime(1900,1,1), //New Years
            new DateTime(1900,7,4), //4th of july
            new DateTime(1900,12, 25) //Christmas
        };


    /// <summary>
    /// Finds the most recent workday from a given date.
    /// </summary>
    /// <param name="date">The date to test.</param>
    /// <returns>The most recent workday.</returns>
    public static DateTime GetLastWorkday(DateTime date)
    {
        //Test for a non working day
        if (IsDayOff(date))
        {
            //We hit a non working day, recursively call this function again on yesterday.
            return GetLastWorkday(date.AddDays(-1));
        }

        //Not a holiday or a weekend, return the current date.
        return date;
    }


    /// <summary>
    /// Returns if the date is work day or not.
    /// </summary>
    /// <param name="testDate">Date to test</param>
    /// <returns>True if the date is a holiday or weekend</returns>
    public static bool IsDayOff(DateTime testDate)
    {
      return date.DayOfWeek == DayOfWeek.Saturday ||
             date.DayOfWeek == DayOfWeek.Sunday || //Test for weekend
             IsMovingHolidy(testDate) || //Test for a moving holiday
             fixedHolidays.Contains(testDate); //Test for a fixed holiday
    }


    /// <summary>
    /// Tests for each of the "dynamic" holidays that do not fall on the same date every year.
    /// </summary>
    private static bool IsMovingHolidy(DateTime testDate)
    {
        //Memoral day is the last Monday in May
        if (testDate.Month == 5 && //The month is May 
                testDate.DayOfWeek == DayOfWeek.Monday && //It is a Monday
                testDate.Day > (31 - 7)) //It lands within the last week of the month.
            return true;

        //Labor day is the first Monday in September
        if (testDate.Month == 9 && //The month is september
                testDate.DayOfWeek == DayOfWeek.Monday &&
                testDate.Day <= 7) //It lands within the first week of the month
            return true;


        //Thanksgiving is the 4th Thursday in November
        if (testDate.Month == 11 && //The month of November
            testDate.DayOfWeek == DayOfWeek.Thursday &&
            testDate.Day > (7*3) && testDate.Day <= (7*4)) //Only durning the 4th week
            return true;

        return false;
    }


    /// <summary>
    /// This comparer only tests the day and month of a date time for equality
    /// </summary>
    private class DayOnlyComparer : IEqualityComparer<DateTime>
    {
        public bool Equals(DateTime x, DateTime y)
        {
            return x.Day == y.Day && x.Month == y.Month;
        }

        public int GetHashCode(DateTime obj)
        {
            return obj.Month + (obj.Day * 12);
        }
    }
}

现在它并没有完全遵循你的规则,这段代码测试一天是否是一个工作日,并继续向后走,直到它达到第一个非工作日。这很容易修改,但是我不想完全解决你的问题所以你可以学到一点(除非我误解了算法,我确实解决了问题,在这种情况下......欢迎你)

您使用它的方式只需输入日期然后用它来决定您是否要返回TRNT

public static string GetDateLabel(DateTime testDate)
{
    if(HolidayTester.IsDayOff(testDate))
        return "NT";
    else
        return "TR";
}

如果您想知道最后一个工作日,可以直接从HolidayTester.GetLastWorkday(DateTime)

拨打该电话