计算时间差去除节假日和周末

maxsport 2014-06-25 10:34:10
高手指点下啊,现在我定义了节假日表和周末holidays:
date isdate
2010-6-14 00:00:00 节假日( y)
2010-6-15 00:00:00 节假日( y)
2010-6-20 00:00:00 周末( y)

需要实现例如:开始时间:2010-6-10 12:00:00 处理时间: 2010-6-14 12:00:00 最后得到处理时长:3.5天(精确到秒)
主要问题是精确到小时分秒怎么处理?是否可以通过函数实现,更高的效率。
...全文
2428 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
maxsport 2014-06-30
  • 打赏
  • 举报
回复
楼上说的对,如果只考虑天的话直接excel里面用networkdays,就可以了。 string sql = "select type as type,company as company,department as department, name as name,subject as subject,node_policy as node_policy,state as state,create_date as create_date,recieve_time as recieve_time,complete_time as complete_time from mystatis where" + where + " order by recieve_time"; DataTable dt = new DataTable(); SqlCommand cmd = new SqlCommand(sql, con); SqlDataAdapter Datapter = new SqlDataAdapter(cmd); Datapter.Fill(dt); string sql2 = "select h_start,h_end from myholidays order by h_start"; DataTable dt2 = new DataTable(); SqlCommand cmd2 = new SqlCommand(sql2, con); SqlDataAdapter dpt = new SqlDataAdapter(cmd2); dpt.Fill(dt2); for(int i=0;i<dt.Rows.Count;i++) { DataRow dr = dt.Rows.Find(dt2); if(dr!=null){ var f1 = DateTime.Parse(dt.Rows[i]["receive_time"].ToString()); var t1 = DateTime.Parse(dt.Rows[i]["complete_time"].ToString()); var result = t1.Subtract(f1); result -= IntersectionOfDateTime(f1, t1, DateTime.Parse(dt2.Rows[i]["h_start"].ToString()), DateTime.Parse(dt2.Rows[i]["h_end"].ToString())); } else{ var f1 = DateTime.Parse(dt.Rows[i]["receive_time"].ToString()); var t1 = DateTime.Parse(dt.Rows[i]["complete_time"].ToString()); var result = t1-f1; } }
於黾 2014-06-30
  • 打赏
  • 举报
回复
我之前做过的计算工作日,只是计算每个月上班几天,而没有精确到小时分秒,所以数据库里存个日期就行了 但是你这个既然要精确到小时,那相应的数据库里就不该只有个日期.
於黾 2014-06-30
  • 打赏
  • 举报
回复
所以你数据库中的节假日就不应该只是2010-6-14 00:00:00这种形式 而是2010-6-14 00:00:00,2010-6-15 00:00:00这种形式,分为开始时间和结束时间, 这样再将总时间抠掉节假日和早午晚的休息时间,循环一下就行了.
maxsport 2014-06-29
  • 打赏
  • 举报
回复
很感谢楼上朋友的回复,我的最终需求是OA里面的流程有接收时间,处理时间,最终反应处理流程的效率,要求可以选择性的排除节假日、周六周日、下班时间分别的不同处理时长,用于分析处理流程的效率。下午6点到第二天早上9点都应该不计算在工作时间之内,这样希望再优化一下。再次特别感谢sp1234.
  • 打赏
  • 举报
回复
另外,我不知道你这个东西到底用于什么产品中。如果你把夜间也算是上班时间,显然就不对。对于大多数程序员来说,下午6点到第二天早上9点都应该不计算在工作时间之内。(当然一些坑爹的牲口程序员,每天上班到晚上9点才回家,不算)
  • 打赏
  • 举报
回复
引用 6 楼 maxsport 的回复:
节假日和周末都是通过数据库里面的表设置的,我放到datatable里面后,怎样跟节假日循环查找,如果是节假日则按上一天的23:59:59作为处理时间。
这显然是有很大误区的。至少有两点明显的: 1. 千万不要以为时间是到 59分59秒。我写59份59.999秒这已经有一些存在的误差了。你写成59秒,误差就更大了。 2. 节假日可不是总是到整好一天。例如有些节假日从1月23日下午到2月10号上午。例如3-8妇女节可能就只有一下午。而某些特定单位的节假,甚至都没有半天,只有更短的两三小时。
bwangel 2014-06-29
  • 打赏
  • 举报
回复
假设你要算时间T1和T2之间实际在工作日发生的时间间隔S(是这个意思吗),可以按这个思路: 1. 先从数据库读取出在T1和T2之间的所有工作日 List<D>。LS的几位都 给出了sql. 2. S= F(T1) + (List<D> - T1 -T2 ) + F(T2) 3. F(T1)= 如果List<D>中包含T1,则返回从T1到T1下一天0点的时间间隔, 如果不包含T1,则返回0 2. F(T2)=如果 List<D>中包含T2, 则返回从T2的0点到T2的时间间隔,如果不包含则返回0
  • 打赏
  • 举报
回复
引用 2 楼 maxsport 的回复:
具体示范下啊,我现在是先查询出来放到datatable里面,怎么循环?
要写出恰当的数据结构! 不要用毫无关系的datatable说事,不要胡乱让乱你自己的思路。
  • 打赏
  • 举报
回复
显然你可以看到
var f1 = DateTime.Parse("2010-6-13 18:10:29");
var t1 = DateTime.Parse("2010-6-20 12:51:10");
计算结果为“4天5小时49分31秒”
  • 打赏
  • 举报
回复
因为你的节假日都是不重叠的,因此只要从需要判断时间段中反复减掉节假日即可。 例如判断时间段 [fr,t1] 与时间段 [f2,t2] 中间重叠了多长时间,可以写
public static TimeSpan IntersectionOfDateTime(DateTime fr1, DateTime to1, DateTime fr2, DateTime to2)
{
    if (fr1 > to2 || fr2 > to1)
        return TimeSpan.Zero;

    var fr = new DateTime(Math.Max(fr1.Ticks, fr2.Ticks));
    var to = new DateTime(Math.Min(to1.Ticks, to2.Ticks));
    return to.Subtract(fr);
}
这是全部核心代码,仅此而已。 现在要判断 2010-6-10 18:00:00 到 2010-6-20 10:00:00 之间相距多长时间,则可以写
var f1 = DateTime.Parse("2010-6-10 18:00:00");
var t1 = DateTime.Parse("2010-6-20 10:00:00");
var result = t1.Subtract(f1);
result -= IntersectionOfDateTime(f1, t1, DateTime.Parse("2010-6-14 00:00:00"), DateTime.Parse("2010-6-14 23:59:59.999"));
result -= IntersectionOfDateTime(f1, t1, DateTime.Parse("2010-6-15 00:00:00"), DateTime.Parse("2010-6-15 23:59:59.999"));
result -= IntersectionOfDateTime(f1, t1, DateTime.Parse("2010-6-20 00:00:00"), DateTime.Parse("2010-6-20 23:59:59.999"));
这就是用 f1、t1 之间的总时间,减去分别与每一个节假日区间的相交时间(如果不想交就会是TimeSpan.Zero),最后得到结果就是“7天零6个小时”。
maxsport 2014-06-29
  • 打赏
  • 举报
回复
按楼上的说法如果刚好节假日收到,如果按一天的话就多减了,会造成负数。我觉得还是应该按照时间段来判断, 比如四个时间节点的交集。
自然框架 2014-06-28
  • 打赏
  • 举报
回复
dt.Select("type in (1,2) and date between '开始' and '结束' ) .length ;//这个就是包含了几个节假日
自然框架 2014-06-28
  • 打赏
  • 举报
回复
看期间内包含了几个节假日,有一个就去掉24小时,就是一天;有两个就去掉两天。 和时分秒没有关系。节假日都是按照整天(24小时0分0秒)计算的吧。 --包含了几个节假日 select count(*) from 节假日表 where date between '工作开始日期' and '工作结束日期' --不带时分秒 开始时间:2010-6-10 12:00:00 处理时间: 2010-6-14 12:00:00 select count(*) from 节假日表 where date between '2010-6-10' and '2010-6-14' 2010-6-14 00:00:00 节假日( y) 2010-6-15 00:00:00 节假日( y) 2010-6-20 00:00:00 周末( y) 然后在计算一下第一天用了多少小时分秒,最后一天用了多少小时分秒。
於黾 2014-06-26
  • 打赏
  • 举报
回复
引用 6 楼 maxsport 的回复:
节假日和周末都是通过数据库里面的表设置的,我放到datatable里面后,怎样跟节假日循环查找,如果是节假日则按上一天的23:59:59作为处理时间。
这个思路不对. 你这样判断,逻辑就太复杂了. 因为有可能开始是节假日,中间是节假日,结尾是节假日,有可能几种同时存在. 你先算出总时间,然后循环节假日表,判断落于这个区间,就将对应的时间扣除.
maxsport 2014-06-26
  • 打赏
  • 举报
回复
节假日和周末都是通过数据库里面的表设置的,我放到datatable里面后,怎样跟节假日循环查找,如果是节假日则按上一天的23:59:59作为处理时间。
maxsport 2014-06-26
  • 打赏
  • 举报
回复
这样两组时间段至少有4种情况需要判断,怎么判断呢C#?
yaotomo 2014-06-26
  • 打赏
  • 举报
回复
去除周末好做,计算机不知道节假日啊 如果节假日是固定某天的话好办,有的不是固定的就不好弄了
天空丶蒋 2014-06-26
  • 打赏
  • 举报
回复

 /// <summary>
        /// 计算某时间段含有假期的天数
        /// </summary>
        /// <param name="date">开始时间</param>
        /// <param name="date1">结束时间</param>
        /// <returns></returns>
        public int JSjqDay(DateTime date,DateTime date1)
        {
            int day = 0;  //假期的天数
            DateTime resultDate1 = date1;
            DateTime dateNow;
            string connStr = ConfigurationManager.AppSettings["ExFlowConnStr"];
            using (SqlConnection conn = new SqlConnection(connStr))
            {
                //type:1,节日 2,工作日
                string SQL = "select date,type from exnewframe..ExHoliday where year >= " + date.Year.ToString();
                SqlDataAdapter adp = new SqlDataAdapter(SQL, conn);
                DataTable dt = new DataTable();
                adp.Fill(dt);
                dateNow = DateTime.Now;
                int n = (date - dateNow).Days; 
                //resultTmp = GetNewDate2(date, dt, ref date1);
                try
                {
                    //Response.Write("<script>alert(\"" + (DateTime.Compare(date, date1) <= 0 )+ "\");</script>");
                    while (DateTime.Compare(date, date1) <= 0)
                    {
                        if (date.DayOfWeek == DayOfWeek.Saturday || date.DayOfWeek == DayOfWeek.Sunday) //周末
                        {
                            if (dt.Select("type=2 and date='" + date.ToString("yyyy-MM-dd 00:00:00.000") + "'").Length > 0) //在工作日中
                            {

                            }
                            else //不在工作日
                            {
                                day++;
                            }
                        }
                        else //不是周末
                        {
                            //LogForYiDongBanGong.WriteLog(result.ToString("yyyy-MM-dd 00:00:00.000") + "||" + trnTime.ToString("yyyy-MM-dd") + "||" + "在节日表中");
                            if (dt.Select("type=1 and date='" + date.ToString("yyyy-MM-dd 00:00:00.000") + "'").Length > 0) //在节日表中
                            {
                                day++;
                            }
                            else //不在节日表中
                            {
                            }
                        }
                        date = date.AddDays(1);
                    }
                }
                catch (Exception ex)
                {
                    Response.Write("786:" + ex.Message);
                } 
            }

            //Response.Write("<script>alert(\"" + date + "||" + date1 + "day" + day + "\");</script>");
            return day;
        }


这样的话只能得到这个时间段中的假期日。 正如前面所说,节假日的这个问题是会动的,所以用这个是不能判断的...

//addDays    计划的天数
//time7  不排除假期的目标天数
//time6 开始的日期
//LinShiDt   临时变量
//result  最终计算的目标天数
LinShiDt = time6.AddDays(addDays + JSjqDay(time6, time7));
                                        result = LinShiDt.AddDays((JSjqDay(time6, LinShiDt)));
                                        DateTime dtLs = DateTime.MinValue;
                                        do
                                        {
                                            dtLs = result.AddDays(JSjqDay(LinShiDt.AddDays(1), result));
                                            LinShiDt = result;
                                            result = dtLs;
                                        }
                                        while (JSjqDay(LinShiDt.AddDays(1), result) > 0);

maxsport 2014-06-25
  • 打赏
  • 举报
回复
具体示范下啊,我现在是先查询出来放到datatable里面,怎么循环?
threenewbee 2014-06-25
  • 打赏
  • 举报
回复
如果是周末,尚可以计算得到,但是如果涉及节假日,只能循环了。不用担心性能,其实这没有多大运算量。

62,074

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧