需要求一个计算时间差的算法
上班时间为早上8:30, 下班时间为下午17:30, 中间12:00-13:00 休息, 实际工作时间为 8:30-12:00 + 13:00-17:30
要求:
传入开始时间和结束时间, 计算开始时间到结束时间之间的工作小时, 
比如开始时间为 2009-08-07 10:00:00,结束时间为 20009-08-11 11:00:00, 我想要的结果是 这个时间段的工作时间,去掉周末,去掉午休,去掉晚上。

解决方案 »

  1.   

    先整除7天 , n(整数部分)*5*8 = x(小时)
    然后取余数(开始时间 + n*7) ~ 结束时间 然后这里面算时间1天天算也行。
    做个循环:循环步跳,开始日期++(天)。
    非工作日不做处理。
    如果是工作日:开始日期+1< 结束日期,则工作时间 = 工作时间 + 8小时。
    否则进入具体1天工作时间的计算。判断过程自己写吧。如果要考虑国定休假日的话,在上面这个结果后面去除此时间段(非周末国定休假日的天数)就行。
      

  2.   

    嘿嘿...刚测试通过了,:)
    关键是计算是同一天还是不同的几天,不同的几天,头尾两天的时间计算比较麻烦,还要判断是连续的两天还是多于两天...例子如下
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
    "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=gb2312">
    <title>求工作时间</title>
    </head>
    <style type="text/css">
    body, td, input{font-family:Verdana; font-size:12px; color:#333333; font-weight:normal;}
    </style>
    <script language="javascript" type="text/javascript">
    function trim(s)
    {
    return s=s.replace(/(^\s*)|(^\s*$)/g,"");
    }
    function getWorkTime()
    {//FUNCTION: 计算工作时间
    //format of FirstTime/LastTime: YYYY-MM-DD hh:mm:ss
    var dt1=trim(document.getElementById("FirstTime").value);
    dt1=dt1.replace("-","/");
    var dt2=trim(document.getElementById("LastTime").value);
    dt2=dt2.replace("-","/");
    var noonRelaxHours=1;
    var d1=new Date(dt1);
    var d2=new Date(dt2);
    var diffHours=0;
    if(d1.getDate()==d2.getDate()){
    //-------same a day-------
    if(d2.getHours() <= 12){ //same in AM
    diffHours=d2.getTime()-d1.getTime();
    }else{ //PM
    diffHours=d2.getTime()-d1.getTime()-noonRelaxHours*60*60*1000;
    }
    }else{
    //-------different day-------
    var tempDT,diffDay=0,startHour=0,endHour=0,strDT="";
    //the START Day
    strDT=d1.getFullYear()+"/"+(d1.getMonth()+1)+"/"+d1.getDate()+" "+"17:30:00";
    tempDT=new Date(strDT);
    //alert(tempDT);
    if(d1.getHours()<12){
    diffHours=tempDT.getTime()-d1.getTime()-noonRelaxHours*60*60*1000;
    }else{
    diffHours=tempDT.getTime()-d1.getTime();
    }

    //the END Day
    strDT=d2.getFullYear()+"/"+(d2.getMonth()+1)+"/"+d2.getDate()+" "+"08:30:00";
    tempDT=new Date(strDT);
    if(d2.getHours()>12){
    diffHours+=d2.getTime()-tempDT.getTime()-noonRelaxHours*60*60*1000;
    }else{
    diffHours+=d2.getTime()-tempDT.getTime();
    }
    //the MIDDLE of first and last day
    diffDay=d2.getDate()-d1.getDate()-1;
    if(diffDay>0){
    diffHours+=diffDay*8*60*60*1000;
    }
    }
    diffHours=diffHours / (1000*60*60);  //convert to Hours
    document.getElementById("WorkTime").value=diffHours;
    }
    </script>
    <body>
    <p><b>按每天的工作时间早上8:30--12:00,下午13:00--17:30这样的安排,
    给定首尾两个时间,计算其中的工作时间</b></p>
    开始时间1:
    <input type="text" id="FirstTime" value="2009-08-07 10:00:00"/> 
    &nbsp;&nbsp;
    结束时间2:
    <input type="text"  id="LastTime" value="2009-08-11 11:00:00" onblur="javascript:getWorkTime();"/>
    &nbsp;&nbsp;
    其中的工作时间为:
    <input type="text" id="WorkTime" name="WorkTime"/>
    小时
    <input type="button" value="Test" onClick="javascript:getWorkTime();">
    </body>
    </html>
    缺点:只能计算本月内的工作时间,跨月需要改进...
      

  3.   


    我用getDate(), getHours 等方法怎么结果都是: NaN?
      

  4.   


    <script type="text/javascript">
    (function(){

    /*********************************************
    函数名: ComputeWorkTime
    功  能: 计算工作时间。
    参  数: T1 开始时间 必须为标准时间格式,例如:2009/08/07 10:00:00
    T2 结束时间 格式与上面相同
    startT1 早上上班时间 (单位:秒) 格式例如:8:30:24 = 8*60*60 + 30*60 + 24
    endT1 早上下班时间 (单位:秒) 格式与上面相同
    startT2 下午上班时间 (单位:秒) 格式与上面相同
    endT2 下午下班时间 (单位:秒) 格式与上面相同
    返 回: 工作总时间数组(去掉周末,去掉午休,去掉晚上) (单位:秒)
    作 者: pillar0514
    *********************************************/ function ComputeWorkTime(T1,T2,startT1,endT1,startT2,endT2){
    T1 = new Date(T1);
    T2 = new Date(T2);
    if(T2-T1 < 0){
    return 0;
    }
    var fulldayTime = endT2 - startT2 + endT1 - startT1;

    //获取起始日期当天的时间:
    function GetFirstDayTime(T){
    if (IsHoliday(T)){
    return 0;
    }
    var _time = T.getHours()*60*60+T.getMinutes()*60+T.getSeconds();
    if( _time <= startT1 ){ //上午上班前
    return fulldayTime;
    }else if(startT1<_time && _time<=endT1){ //上午
    return ( endT1 - _time + endT2 - startT2 );
    }else if(endT1<_time && _time<=startT2){ //中午
    return ( endT2 - startT2 );
    }else if(startT2<_time && _time<=endT2){ //下午
    return ( endT2 - _time );
    }else{ //下午下班后
    return 0;
    }
    }

    //获取结束日期当天的时间:
    function GetLastDayTime(T){
    if (IsHoliday(T)){
    return 0;
    }
    var _time = T.getHours()*60*60+T.getMinutes()*60+T.getSeconds();
    if( _time <= startT1 ){ //上午上班前
    return 0;
    }else if(startT1<_time && _time<=endT1){ //上午
    return ( _time - startT1 );
    }else if(endT1<_time && _time<=startT2){ //中午
    return ( endT1 - startT1 );
    }else if(startT2<_time && _time<=endT2){ //下午
    return ( _time - startT2 + endT1 - startT1 );
    }else{ //下午下班后
    return ( fulldayTime );
    }
    }

    //获取起始日期到结束日期之间的时间:
    function GetBetweenTime(t1,t2){
    var t1 = new Date( t1.getYear()+"/"+(t1.getMonth()+1)+"/"+t1.getDate() );
    var t2 = new Date( t2.getYear()+"/"+(t2.getMonth()+1)+"/"+t2.getDate() );
    var oneday = 24*60*60*1000;
    var t = t2;
    var _time = 0;
    var _tmpDate;
    while(t>t1-0+oneday){ //循环每天,排除头一天和末一天
    t = t - oneday;
    _tmpDate = new Date(t);
    if(! IsHoliday(_tmpDate) ){ //排除节假日
    _time += fulldayTime;
    }
    }
    return _time;
    }

    //排除节假日:
    function IsHoliday(T){
    var _Month = T.getMonth()+1;
    var _Date = T.getDate();
    var _Day = T.getDay();
    if(_Day==6||_Day==0){ //周六日
    return true;
    }
    switch(_Month+"."+_Date){
    case "10.1": return true; //在这里添加节假日
    case "10.2": return true;
    case "10.3": return true;
    case "5.1": return true;
    }
    return false;
    } return GetFirstDayTime(T1) + GetBetweenTime(T1,T2) + GetLastDayTime(T2);
    } var worktime = ComputeWorkTime("2009/08/07 10:00:00", "2009/08/11 11:00:00", 8*60*60+30*60, 12*60*60, 13*60*60, 17*60*60+30*60); alert("共"+worktime+"秒\n"+Math.floor(worktime/3600)+"小时\n"+(worktime%3600)/60+"分钟");})();
    </script>
      

  5.   


    ?!   var d=new Date();
    alert("号:"+d.getDate()+"   小时:"+d.getHours());
    如上这样有错吗?不会吧....区分大小写,你注意哦,
      

  6.   

    浏览器兼容的时候出问题了,改进:
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>无标题文档</title>
    </head><body>
    </body>
    </html>
    <script type="text/javascript">
    (function(){

    /*********************************************
    函数名: ComputeWorkTime
    功  能: 计算工作时间。
    参  数: T1 开始时间 必须为标准时间格式,例如:2009/08/07 10:00:00
    T2 结束时间 格式与上面相同
    startT1 早上上班时间 (单位:秒) 格式例如:8:30:24 = 8*60*60 + 30*60 + 24
    endT1 早上下班时间 (单位:秒) 格式与上面相同
    startT2 下午上班时间 (单位:秒) 格式与上面相同
    endT2 下午下班时间 (单位:秒) 格式与上面相同
    返 回: 工作总时间数组(去掉周末,去掉午休,去掉晚上) (单位:秒)
    作 者: pillar0514
    *********************************************/ function ComputeWorkTime(T1,T2,startT1,endT1,startT2,endT2){
    T1 = new Date(T1);
    T2 = new Date(T2);
    if(T2-T1 < 0){
    return 0;
    }
    var fulldayTime = endT2 - startT2 + endT1 - startT1;

    //获取起始日期当天的时间:
    function GetFirstDayTime(T){
    if (IsHoliday(T)){
    return 0;
    }
    var _time = T.getHours()*60*60+T.getMinutes()*60+T.getSeconds();
    if( _time <= startT1 ){ //上午上班前
    return fulldayTime;
    }else if(startT1<_time && _time<=endT1){ //上午
    return ( endT1 - _time + endT2 - startT2 );
    }else if(endT1<_time && _time<=startT2){ //中午
    return ( endT2 - startT2 );
    }else if(startT2<_time && _time<=endT2){ //下午
    return ( endT2 - _time );
    }else{ //下午下班后
    return 0;
    }
    }

    //获取结束日期当天的时间:
    function GetLastDayTime(T){
    if (IsHoliday(T)){
    return 0;
    }
    var _time = T.getHours()*60*60+T.getMinutes()*60+T.getSeconds();
    if( _time <= startT1 ){ //上午上班前
    return 0;
    }else if(startT1<_time && _time<=endT1){ //上午
    return ( _time - startT1 );
    }else if(endT1<_time && _time<=startT2){ //中午
    return ( endT1 - startT1 );
    }else if(startT2<_time && _time<=endT2){ //下午
    return ( _time - startT2 + endT1 - startT1 );
    }else{ //下午下班后
    return ( fulldayTime );
    }
    }

    //获取起始日期到结束日期之间的时间:
    function GetBetweenTime(t1,t2){
    var t1 = new Date( t1.getFullYear()+"/"+(t1.getMonth()+1)+"/"+t1.getDate() );
    var t2 = new Date( t2.getFullYear()+"/"+(t2.getMonth()+1)+"/"+t2.getDate() );
    var oneday = 24*60*60*1000;
    var t = t2;
    var _time = 0;
    var _tmpDate;
    while(t > (t1-0+oneday) ){ //循环每天,排除头一天和末一天
    t = t - oneday;
    _tmpDate = new Date(t);
    if(! IsHoliday(_tmpDate) ){ //排除节假日
    _time += fulldayTime;
    }
    }
    return _time;
    }

    //排除节假日:
    function IsHoliday(T){
    var _Month = T.getMonth()+1;
    var _Date = T.getDate();
    var _Day = T.getDay();
    if(_Day==6||_Day==0){ //周六日
    return true;
    }
    switch(_Month+"."+_Date){
    case "10.1": return true; //在这里添加节假日
    case "10.2": return true;
    case "10.3": return true;
    case "5.1": return true;
    }
    return false;
    } return GetFirstDayTime(T1) + GetBetweenTime(T1,T2) + GetLastDayTime(T2);
    } var worktime = ComputeWorkTime("2009/08/07 10:00:00", "2009/08/11 11:00:00", 8*60*60+30*60, 12*60*60, 13*60*60, 17*60*60+30*60); alert( "共"+worktime + "秒\n" + Math.floor(worktime/3600) + "小时\n" + (worktime%3600)/60 + "分钟" );})();</script>
      

  7.   

    修改完成了...:),支持跨年跨月分跨天的情况,精确到0.01小时,支持 YYYY-MM-DD hh:mm:ss, 和 YYYY/MM/DD hh:mm:ss 的时间格式输入,兼容MS ,FF, NS IE
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
    "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=gb2312">
    <title>求工作时间</title>
    </head>
    <style type="text/css">
    body, td, input{font-family:Verdana; font-size:12px; color:#333333; font-weight:normal;}
    </style>
    <script language="javascript" type="text/javascript">
    /*
    function: 计算工作时间,
    created: 2009-08-10
    */
    create: 2009-08-10
    function trim(s)
    {
    return s=s.replace(/(^\s*)|(^\s*$)/g,"");
    }
    function getWorkTime()
    {//FUNCTION: 计算工作时间
    //format of FirstTime/LastTime: YYYY-MM-DD hh:mm:ss, 支持是 YYYY/MM/DD hh:mm:ss 格式
    var dt1=trim(document.getElementById("FirstTime").value);
    dt1=dt1.replace(/[-]/g,"/");
    var dt2=trim(document.getElementById("LastTime").value);
    dt2=dt2.replace(/[-]/g,"/");
    var d1=new Date(dt1);
    var d2=new Date(dt2);
    if(d2<d1) {
    alert("结束时间应该比开始时间要晚/大,请输入正确");
    return false;
    }
    var noonRelaxHours=1; //中午休息,根据需要修改,单位小时
    var holidayNum=0; //节假日天数,根据需要修改,单位天
    holidayNum=parseInt(trim(document.getElementById("holidayDay").value),10);  
    var dayTime=24*60*60*1000;
    var dayWorkTime=8*60*60*1000;var diffHours=0;
    if(d1.getFullYear()==d2.getFullYear() && d1.getMonth()==d2.getMonth() && d1.getDate()==d2.getDate()){
    //-------same a day-------
    if(d2.getHours() <= 12){ //same in AM
    diffHours=d2.getTime()-d1.getTime();
    }else{ //PM
    diffHours=d2.getTime()-d1.getTime()-noonRelaxHours*60*60*1000;
    }
    }else{
    //-------different day-------
    var tempDT,diffDay=0,diffTime=0,startHour=0,endHour=0,strDT="";
    //the START Day
    strDT=d1.getFullYear()+"/"+(d1.getMonth()+1)+"/"+d1.getDate()+" "+"17:30:00";
    tempDT=new Date(strDT);
    if(d1.getHours()<12){
    diffHours=tempDT.getTime()-d1.getTime()-noonRelaxHours*60*60*1000;
    }else{
    diffHours=tempDT.getTime()-d1.getTime();
    }

    //the END Day
    strDT=d2.getFullYear()+"/"+(d2.getMonth()+1)+"/"+d2.getDate()+" "+"08:30:00";
    tempDT=new Date(strDT);
    if(d2.getHours()>12){
    diffHours+=d2.getTime()-tempDT.getTime()-noonRelaxHours*60*60*1000;
    }else{
    diffHours+=d2.getTime()-tempDT.getTime();
    } //the MIDDLE days
    diffTime=d2.getTime()-d1.getTime();
    var tempA,tempB,tempC;
    tempA=new Date(d1.getFullYear()+"/"+(d1.getMonth()+1)+"/"+d1.getDate());
    tempB=new Date(d2.getFullYear()+"/"+(d2.getMonth()+1)+"/"+d2.getDate());
    tempC=tempB;
    while(tempC>(tempA-0+dayTime)){  //首尾特殊的2天去掉
    tempC=tempC-dayTime;
    diffDay+=1; //get middle x Day(s)
    }
    diffHours+=diffDay*dayWorkTime;

    }

    diffHours=diffHours-holidayNum*dayWorkTime; //按每天工作8小时,减去节假日和周末的天数if(diffHours<0){
    diffHours=0;
    }else{
    //diffHours=Math.floor(diffHours / (1000*60*60));  //简单精确到小时整数
    diffHours=diffHours / (1000*60*60);  //转换成小时,精确到0.01小时
    var r1,r2,r3;
    r1=new String(diffHours);
    if(r1.indexOf(".")>0){
    r2=r1.split(".");
    r3=r2[0]+"."+r2[1].substr(0,2);
    diffHours=r3;
    }  
    }
    document.getElementById("WorkTime").value=diffHours;
    }
    </script>
    <body>
    <p><b>按每天的工作时间早上8:30--12:00,下午13:00--17:30这样的安排,给定首尾两个时间,计算其中的工作时间</b></p>
    开始时间1:
    <input type="text" id="FirstTime" value="2009-08-07 10:00:00"/> 
    &nbsp;&nbsp;
    结束时间2:
    <input type="text"  id="LastTime" value="2009-08-11 11:00:00" onblur="javascript:getWorkTime();"/>
    &nbsp;去掉其间节假日和周末共:&nbsp;
    <input type="text" id="holidayDay" name="holidayDay" value="0" size="5"/ onKeyUp="this.value=this.value.replace(/[^0-9]/g,'');">
    天,&nbsp;&nbsp;
    其中的工作时间为:
    <input type="text" id="WorkTime" name="WorkTime"/>
    小时
    <input type="button" value="Test" onClick="javascript:getWorkTime();">
    </body>
    </html>
      

  8.   

    感谢  pillar0514 和 shenzhenNBA的回答,
    不过2位都没有派出周六周天, shenzhenNBA的方法需要手动录入节假日天数
    能否判断当前日期是否周六周天?
      

  9.   

    不好意思 pillar0514的有排除星期6、天