簡體   English   中英

給定的DateTime鍵在詞典中不存在

[英]The given DateTime key was not present in the dictionary

我是C#和編程的初學者。 我正在嘗試計算一些DateTime變量。 第一種被稱為dDate和第二dDate1 (前一天dDate ),第三dDate2 (第二前一天dDate ,即,前一天dDate1 ,第四) dDate3 (第三前一天dDate ,即dDate1的前第二天和dDate2的前一天)。 他們一定不是假期或周末!

我已經將所有節假日和周末存儲在名為nd<DateTime, string>的字典中。 關鍵的DateTime具有從一系列日期2011-01-012013-01-01 ,一步一天,值string或者是TRNT ,一個字符串變量而不是布爾值。 如果是周末或假日,則字符串為NT ,否則為TR

我想做的是dDate是周末或假日,減去一天。 例如, dDate是假期的2012-01-02 ,將dDate更改為2012-01-01 ,並且由於它是周末(星期日),所以將其更改為2011-12-31 ,再次是周末,則更改dDate2011-12-30 dDate1dDate2dDate3

這里的問題是我的代碼對於dDate可以正常工作。 但是它給出了一個錯誤:

給定的鍵在字典中不存在

當我為dDate1dDate2dDate3做同樣的事情時。 該代碼附在下面:

 private Dictionary<DateTime, string> noDates;
 ...
 noDates = new Dictionary<DateTime, string>();

 public void ImportNoDate()
 {
      string str;
      string[] line = new string[0];
      while ((str = reader.ReadLine()) != null) 
      {
         line = str.Split(',');
         String date = line[1];
         String flag = line[2];//flag is "NT" or "TR"
         String[] tmp = date.Split('-');
         date = Convert.ToInt32(tmp[0]) + "-" + Convert.ToInt32(tmp[1]) + "-" + Convert.ToInt32(tmp[2]);

         DateTime noDate = DateTime.Parse(date);
         noDates.Add(noDate, flag);
     }
  }

public void ImportdDate()
{
    ...
    DDates dd = new DDates(dDate, noDates); //dDate is defined similar to noDate, it is just another //series of date
}

    //DDates is an auxiliary cs file called DDates.cs
    public DDates(DateTime dd, Dictionary<DateTime, string> nd)
    {
         dDate1 = dDate.AddDays(-1);
         dDate1 = dDate.AddDays(-2);
         dDate3 = dDate.AddDays(-3);

       // dDate is imported from data file and has been Parse
      // to DateTime and it is something like
      // 2012-01-01 12:00:00 AM

     if (nd.ContainsKey(dDate))
     {
        while (nd[dDate].Contains("NT"))
       {
          dDate = dDate.AddDays(-1);
       }
    }

   //It works fine till here:
   if (nd.ContainsKey(dDate1))
   {
      //It gives "the given key was not present in the dictionary" here:
      while (nd[dDate1].Contains("NT"))
      {
        dDate1 = dDate1.AddDays(-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);
        }
    }
}

現在,它不完全遵循您的規則,此代碼測試一天是否為工作日,並一直向后走,直到遇到第一個非工作日為止。 修改起來很容易,但是我不想完全解決您的問題,因此您可以學習一些(除非我誤解了算法,並且確實解決了問題,在這種情況下……不客氣)

您將其使用的方式只是放在一個日期中,然后使用該日期來決定要返回TR還是NT

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

如果您想知道最后一個工作日,可以直接從HolidayTester.GetLastWorkday(DateTime)致電

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM