这几天做项目遇到一个头疼的问题,是关于计算计划天数的,刚开始是这么计算的:用计划完成时间减去计划开始时间,中间的时间差就是工天数,但是这样完全不行,因为法定节假日和双休日是不能考虑在计划工天里头的,我冥思苦想了一个晚上,重要找到了解决方案;思路如下:
1\配置一张节假日表,用于存储每一年国家规定的法定放假日期;
2\定义一个数组,用于存储放假日期,包括双休;
3\再定义一个数组,存储全年的日期,判断放假休息日期是否在全年日期的数组里面,如果是则将放假日期移除,剩下的日期即为上班工作的日期;
4\根据索引找出具体日期,索引的值为实际计划天数,索引所对应的日期即为计划结束日期,反过来,计划完成日期的索引减去开始时间的索引即为实际天数;
部分代码如下:
ArrayList array = new ArrayList();//定义一个全局数组变量
ArrayList array1 = new ArrayList();//存放国家法定节日的调休时间
ArrayList newArray = new ArrayList();//一年中所有的工作日
private DateTime dtStartTime;//定义一个开始时间
private DateTime dtEndTime;//定义一个结束时间
ArrayList array1 = new ArrayList();//存放国家法定节日的调休时间
ArrayList newArray = new ArrayList();//一年中所有的工作日
private DateTime dtStartTime;//定义一个开始时间
private DateTime dtEndTime;//定义一个结束时间
public ArrayList GetHolidayDay()//国家法定节假日
{
#region 国家法定节假日
SqlConnection conn = new SqlConnection(LoginForm.sqlConnString);
conn.Open();
string strsql = "select 开始时间,结束时间 from 法定假日表 where 年份='" + DateTime.Now.Year.ToString() + "'";
SqlDataAdapter adapter = new SqlDataAdapter(strsql, conn);
DataTable table = new DataTable();
adapter.Fill(table);
for (int i = 0; i < table.Rows.Count; i++)
{
dtStartTime = Convert.ToDateTime(table.Rows[i]["开始时间"].ToString());//节假日开始时间
dtEndTime = Convert.ToDateTime(table.Rows[i]["结束时间"].ToString());//节假日结束时间
System.TimeSpan tsdiffer = dtEndTime - dtStartTime;//获取节假日开始时间到结束时间的天数
int idiffer = tsdiffer.Days + 1;
for (int j = 0; j < idiffer; j++)
{
DateTime dtHoliday = dtStartTime.Date.AddDays(j);
array.Add(dtHoliday);
}
}
conn.Close();
#endregion
#region 获取一年中所有双休日
string strGetYear = DateTime.Now.Year.ToString() + "-01-01";
DateTime dt = Convert.ToDateTime(strGetYear);//当年的第一天
for (int i = 0; i < 366; i++)
{
DateTime StartTime = dt.Date.AddDays(i);
if (StartTime.DayOfWeek == DayOfWeek.Saturday || StartTime.DayOfWeek == DayOfWeek.Sunday)
{
array.Add(StartTime);//将一年中所有双休日存放在数组中
}
}
#endregion
#region 计算因国家调整的公休时间,即为在制定工期中上班的情况
string strTXTime = null;//法定调休时间
string strsql1 = "select 调休时间 from 法定假日表";
SqlDataAdapter adapter1 = new SqlDataAdapter(strsql1, conn);
DataTable mytable1 = new DataTable();
adapter1.Fill(mytable1);
for (int i = 0; i < mytable1.Rows.Count; i++)//找出所有调休时间,将调休的日期保 存在一个数组中
{
strTXTime = mytable1.Rows[i]["调休时间"].ToString().Trim();
if (strTXTime.Length > 10)//判断调休时间中是否有多个时间字段(此处默认为 两个日期)
{
array1.Add(strTXTime.Substring(0, 10).Trim());
array1.Add(strTXTime.Substring(strTXTime.Length - 10, 10));
}
else
{
array1.Add(strTXTime.ToString());
for (int k = 0; k < array1.Count; k++)
{
if (array1[k].ToString() == "")
{
array1.RemoveAt(k);//如果出现空值则将控制移除
}
}
}
}
for (int i = 0; i < array1.Count;i++ )
{
Convert.ToDateTime(array1[i].ToString());
}
#endregion
#region 移除数组中周六周日上班的情况
for (int i = 0; i < array1.Count;i++ )
{
for (int j = 0; j < array.Count;j++ )
{
if (array1[i]==array[j])
{
array.RemoveAt(j);
}
}
}
#endregion
#region 删除数组中重复元素
for (int i = 0; i < array.Count; i++)
for (int j = i + 1; j < array.Count; j++)
{
if (array[i].Equals(array[j]))
{
array.RemoveAt(j);
}
}
#endregion
#region 一年中所有的工作日
for (int i = 0; i < 365;i++ )//一年以365天计算
{
string strYear = DateTime.Now.Year.ToString() + "-01-01";
DateTime dtTime = Convert.ToDateTime(strYear);//当年的第一天
DateTime dtKAISHI = dtTime.Date.AddDays(i);
newArray.Add(dtKAISHI);//获取一年的所有日期
}
#endregion
#region 移除一年中所有休息的日期,剩下的就是工作日
for (int i = 0; i < array.Count;i++ )
{
for (int j = 0; j < newArray.Count;j++ )
{
if (array[i].Equals(newArray[j]))
{
newArray.RemoveAt(j);
}
}
}
#endregion
return newArray;
}
{
#region 国家法定节假日
SqlConnection conn = new SqlConnection(LoginForm.sqlConnString);
conn.Open();
string strsql = "select 开始时间,结束时间 from 法定假日表 where 年份='" + DateTime.Now.Year.ToString() + "'";
SqlDataAdapter adapter = new SqlDataAdapter(strsql, conn);
DataTable table = new DataTable();
adapter.Fill(table);
for (int i = 0; i < table.Rows.Count; i++)
{
dtStartTime = Convert.ToDateTime(table.Rows[i]["开始时间"].ToString());//节假日开始时间
dtEndTime = Convert.ToDateTime(table.Rows[i]["结束时间"].ToString());//节假日结束时间
System.TimeSpan tsdiffer = dtEndTime - dtStartTime;//获取节假日开始时间到结束时间的天数
int idiffer = tsdiffer.Days + 1;
for (int j = 0; j < idiffer; j++)
{
DateTime dtHoliday = dtStartTime.Date.AddDays(j);
array.Add(dtHoliday);
}
}
conn.Close();
#endregion
#region 获取一年中所有双休日
string strGetYear = DateTime.Now.Year.ToString() + "-01-01";
DateTime dt = Convert.ToDateTime(strGetYear);//当年的第一天
for (int i = 0; i < 366; i++)
{
DateTime StartTime = dt.Date.AddDays(i);
if (StartTime.DayOfWeek == DayOfWeek.Saturday || StartTime.DayOfWeek == DayOfWeek.Sunday)
{
array.Add(StartTime);//将一年中所有双休日存放在数组中
}
}
#endregion
#region 计算因国家调整的公休时间,即为在制定工期中上班的情况
string strTXTime = null;//法定调休时间
string strsql1 = "select 调休时间 from 法定假日表";
SqlDataAdapter adapter1 = new SqlDataAdapter(strsql1, conn);
DataTable mytable1 = new DataTable();
adapter1.Fill(mytable1);
for (int i = 0; i < mytable1.Rows.Count; i++)//找出所有调休时间,将调休的日期保 存在一个数组中
{
strTXTime = mytable1.Rows[i]["调休时间"].ToString().Trim();
if (strTXTime.Length > 10)//判断调休时间中是否有多个时间字段(此处默认为 两个日期)
{
array1.Add(strTXTime.Substring(0, 10).Trim());
array1.Add(strTXTime.Substring(strTXTime.Length - 10, 10));
}
else
{
array1.Add(strTXTime.ToString());
for (int k = 0; k < array1.Count; k++)
{
if (array1[k].ToString() == "")
{
array1.RemoveAt(k);//如果出现空值则将控制移除
}
}
}
}
for (int i = 0; i < array1.Count;i++ )
{
Convert.ToDateTime(array1[i].ToString());
}
#endregion
#region 移除数组中周六周日上班的情况
for (int i = 0; i < array1.Count;i++ )
{
for (int j = 0; j < array.Count;j++ )
{
if (array1[i]==array[j])
{
array.RemoveAt(j);
}
}
}
#endregion
#region 删除数组中重复元素
for (int i = 0; i < array.Count; i++)
for (int j = i + 1; j < array.Count; j++)
{
if (array[i].Equals(array[j]))
{
array.RemoveAt(j);
}
}
#endregion
#region 一年中所有的工作日
for (int i = 0; i < 365;i++ )//一年以365天计算
{
string strYear = DateTime.Now.Year.ToString() + "-01-01";
DateTime dtTime = Convert.ToDateTime(strYear);//当年的第一天
DateTime dtKAISHI = dtTime.Date.AddDays(i);
newArray.Add(dtKAISHI);//获取一年的所有日期
}
#endregion
#region 移除一年中所有休息的日期,剩下的就是工作日
for (int i = 0; i < array.Count;i++ )
{
for (int j = 0; j < newArray.Count;j++ )
{
if (array[i].Equals(newArray[j]))
{
newArray.RemoveAt(j);
}
}
}
#endregion
return newArray;
}