最近,在.net项目中需要实现计算两个日期间的工作日总数,下面简单介绍一下其实现过程 !
先介绍一下计算逻辑:
1.初始化某一年中的所有周六和周日,比如初始化2008年的所有周六、周日,存入表ConfigDate中;
2.添加周六、周日外的其它节假日,比如国庆节、五一节、元旦等至表ConfigDate中;
3.查询某年某月中的所有节假日,并能对某一节假日进行设置其有效性,比如我某个周六加班,则设置该周六假日无效,实际上该天当计算的时候也是工作日;
4.当输入开始日期和结束日期后,把开始日期至结束日期的每一天与ConfigDate表中所有有效节假日进行对比,如果没有找到则工作日总数加1;
最近,在.net项目中需要实现计算两个日期间的工作日总数,下面简单介绍一下实现过程 !
一、先介绍一下计算逻辑:
1.初始化某一年中的所有周六和周日,比如初始化2008年的所有周六、周日,存入表ConfigDate中;
2.添加周六、周日外的其它节假日,比如国庆节、五一节、元旦等至表ConfigDate中;
3.查询某年某月中的所有节假日,并能对某一节假日进行设置其有效性,比如我某个周六加班,则设置该周六假日无效,实际上该天当计算的时候也是工作日;
4.当输入开始日期和结束日期后,把开始日期至结束日期的每一天与ConfigDate表中所有有效节假日进行对比,如果没有找到则工作日总数加1;
二、计算工作日总数的操作类
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
namespace FLX.Portal.Web
{
/// <summary>
/// 计算开始日期到结束日期内的工作日
/// 2008-09-19
/// </summary>
public class CalculateWorkDay
{
#region 构造函数
public CalculateWorkDay()
{
//
// TODO: 在此处添加构造函数逻辑
//
}
#endregion
#region 计算工作日天数
public static int CalculateWorkDays(DateTime BeginDate, DateTime EndDate)
{
string sql = "select * from ConfigDate where state='1'";
DataTable dt = new DataTable();//dt为所有有效的休息节假日数据源
dt = FLX.ORM.BrokerFactory.GetBroker("Yyjcpt").DataAccess.ExecuteDataTable(sql);
int workdays = 0;//返回值,即EndDate和BeginDate之间的工作日数
System.TimeSpan tsDiffer = EndDate.Date - BeginDate.Date;//计算EndDate和BeginDate之间相差多少天
int intDiffer = tsDiffer.Days + 1;//相差天数的int值
for (int i = 0; i < intDiffer; i++)//从BeginDate开始一天天加,判断临时的日期值是不是节假日,如果不是节假日,则该天为工作日,workdays加1
{
DateTime TempDate = BeginDate.Date.AddDays(i);
if (dt.Rows.Count > 0)
{
for (int j = 0; j < dt.Rows.Count; j++)
{
if (TempDate.Date == Convert.ToDateTime(dt.Rows[j]["RestDate"].ToString()).Date)
{
break;
}
if (TempDate.Date != Convert.ToDateTime(dt.Rows[j]["RestDate"].ToString()).Date && j == dt.Rows.Count - 1)
{
workdays++;
}
}
}
else
{
workdays++;
}
}
return workdays;
}
#endregion
#region 调用示例及说明
//DateTime begindate = Convert.ToDateTime(this.TxtBeginDate.Text.Trim());
//DateTime enddate = Convert.ToDateTime(this.TxtEndDate.Text.Trim());
//int workdays = CalculateWorkDay.CalculateWorkDays(begindate,enddate);
//this.TxtDays.Text = workdays.ToString();
#endregion
}
}
三、节假日初始化代码
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
namespace FLX.Portal.Web
{
public partial class InitHoliday : PortalPage
{
protected void Page_Load(object sender, EventArgs e)
{
if (!this.IsPostBack)
{
string date = DateTime.Now.Date.Year.ToString();
this.DDLYear.SelectedValue = date;
}
}
protected void BtnInit_Click(object sender, EventArgs e)
{
DateTime begindate = Convert.ToDateTime(this.DDLYear.SelectedValue + "-01-01");
DateTime enddate = Convert.ToDateTime(this.DDLYear.SelectedValue + "-12-31");
System.TimeSpan tsDiffer = enddate.Date - begindate.Date;
int intDiffer = tsDiffer.Days + 1;
for (int i = 0; i < intDiffer; i++)
{
DateTime dtTemp = begindate.Date.AddDays(i);
if (dtTemp.DayOfWeek == System.DayOfWeek.Sunday)
{
string sqlquery = "select * from ConfigDate where RestDate='" + dtTemp + "'";
DataTable dt = new DataTable();
dt = FLX.ORM.BrokerFactory.GetBroker("Yyjcpt").DataAccess.ExecuteDataTable(sqlquery);
if (dt.Rows.Count == 0)
{
string sql = "insert into ConfigDate(RestDate,State,Remark) values('" + dtTemp + "','1','星期日')";
FLX.ORM.BrokerFactory.GetBroker("Yyjcpt").DataAccess.ExecuteNonQuery(sql);
}
}
if (dtTemp.DayOfWeek == System.DayOfWeek.Saturday)
{
string sqlquery = "select * from ConfigDate where RestDate='" + dtTemp + "'";
DataTable dt = new DataTable();
dt = FLX.ORM.BrokerFactory.GetBroker("Yyjcpt").DataAccess.ExecuteDataTable(sqlquery);
if (dt.Rows.Count == 0)
{
string sql = "insert into ConfigDate(RestDate,State,Remark) values('" + dtTemp + "','1','星期六')";
FLX.ORM.BrokerFactory.GetBroker("Yyjcpt").DataAccess.ExecuteNonQuery(sql);
}
}
}
string strmessage = "<script language=javascript>alert('" + this.DDLYear.SelectedItem.Text + "周末假日初始化成功!')</script>";
Page.RegisterStartupScript("jump", strmessage);
}
}
}
四、表ConfigDate的结构
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[ConfigDate](
[GUID] [varchar](50) COLLATE Chinese_PRC_CI_AS NOT NULL CONSTRAINT [DF_ConfigDate_GUID] DEFAULT (newid()),
[RestDate] [datetime] NULL,
[State] [varchar](50) COLLATE Chinese_PRC_CI_AS NULL,
[Remark] [varchar](100) COLLATE Chinese_PRC_CI_AS NULL,
CONSTRAINT [PK_ConfigDate_1] PRIMARY KEY CLUSTERED
(
[GUID] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'1表示有效的休息日期,2表示无效的休息日期' ,@level0type=N'SCHEMA', @level0name=N'dbo', @level1type=N'TABLE', @level1name=N'ConfigDate', @level2type=N'COLUMN', @level2name=N'State'
五、效果展示
![](https://www.cnblogs.com/images/cnblogs_com/dreamof/workday1.jpg)
![](https://www.cnblogs.com/images/cnblogs_com/dreamof/workday2.jpg)
![](https://www.cnblogs.com/images/cnblogs_com/dreamof/workday3.jpg)
![](https://www.cnblogs.com/images/cnblogs_com/dreamof/workday4.jpg)