字典中不存在给定的日期时间键
本文关键字:日期 时间 不存在 字典 | 更新日期: 2023-09-27 18:33:19
我是C#和编程的初学者。我正在尝试计算一些DateTime
变量。第一个称为dDate
,第二个dDate1
(dDate
的前一天(,第三个dDate2
(dDate
的第二天,即dDate1
的前一天(,第四个dDate3
(dDate
的前三天,即dDate1
的第二天和dDate2
的前一天(。它们一定不是假期或周末!
我把所有的假期和周末都存储在一本名为nd<DateTime, string>
的字典中。键DateTime
有一系列从 2011-01-01
到 2013-01-01
的日期,一步一步,值string
要么是 TR
要么是 NT
,是一个字符串变量,但不是布尔值。如果是周末或节假日,字符串NT
,否则TR
。
我想做的是dDate
是周末或节假日,减去一天。例如,dDate
2012-01-02
是假日,将dDate
更改为2012-01-01
,并且由于是周末(星期日(,将其更改为2011-12-31
,并且又是周末,将dDate
更改为2011-12-30
。与dDate1
、dDate2
和dDate3
相同。
这里的问题是我的代码适用于dDate
.但它给出了一个错误:
字典中不存在给定的键
当我为dDate1
、dDate2
或dDate3
做同样的事情时。代码附在下面:
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)
拨打