帮忙解决个日期相关的JS问题

 <!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        请假开始时间:<input type="datetime-local" />
        请假结束时间:<input type="datetime-local" />
    </body>
</html>

早上9点上班,中午12点-13点休息,下午18点下班
最后需要能计算出一个数组,数组包含了请假的日期和请假时间,比如从2017年8月2日13:00 请假到2017年8月5日12:00应该能输出:

day[0]=[‘year’:2017,‘month’:8,'day' :2,'hour':5]
day[1]=[‘year’:2017,‘month’:8,'day' :3,'hour':8]
day[2]=[‘year’:2017,‘month’:8,'day' :4,'hour':8]
day[3]=[‘year’:2017,‘month’:8,'day' :5,'hour':3]

请各位大神帮帮忙 谢谢了

直接发送sql从后台的数据库获取

<!DOCTYPE html>






请假开始时间:
请假结束时间:
/** * 将时间格式化 ,补0 * 2016-6-17 --> 2016-06-17 * @param n */ function sup(n) { return (n < 10) ? '0' + n : n; } var Week = ['日', '一', '二', '三', '四', '五', '六']; /** * 获取时间分散值 * 年、月、日、周、时、分、秒 等 * @param key 匹配的片段值 */ Date.prototype.part = function (key) { switch (key) { case 'year' : return this.getFullYear(); case 'month' : return sup(this.getMonth() + 1); case 'day' : return sup(this.getDate()); case 'week' : return Week[this.getDay()]; case 'wy' : return this.WeekNumOfYear(); case 'hours' : return sup(this.getHours()); case 'minutes' : return sup(this.getMinutes()); case 'seconds' : return this.getSeconds(); default : return ""; } }; //YYYY-MM-DD HH:mm:ss Date.prototype.toLocaleString = function () { return this.getFullYear() + "-" + (this.getMonth() + 1) + "-" + this.getDate() + " " + this.getHours() + ":" + this.getMinutes() + ":" + this.getSeconds(); }; function query() { //获取选择的开始时间和结束时间 var startValue = document.getElementById('startTime').value; var endValue = document.getElementById('endTime').value; if (startValue == "") { return alert("请选择开始时间"); } if (endValue == "") { return alert("请选择结束时间"); } var startDate = new Date(startValue); var endDate = new Date(endValue); //除去带T时间格式 startDate = new Date(startDate.toISOString().replace(/T/g, ' ').replace(/\.[\d]{3}Z/, '')); endDate = new Date(endDate.toISOString().replace(/T/g, ' ').replace(/\.[\d]{3}Z/, '')); var startMS = startDate.getTime(); var endMS = endDate.getTime(); if (startMS - endMS >= 0) return alert("开始时间不能小于结束时间 或 与结束时间相同"); var dayMS = 1000 * 60 * 60 * 24;//毫秒 *1000 *60 *60 *24 = 天数 //获取天差 var days = (endMS - startMS) / dayMS; //获取开始时间和结束时候的年份、月份、日期 小时 // var startDateYear = startDate.part('year'); // var endDateYear = endDate.part('year'); // // var startDateMonth = startDate.part('month'); // var endDateMonth = endDate.part('month'); // // var startDateDay = startDate.part('day'); // var endDateDay = endDate.part('day'); var startDateHours = startDate.part('hours'); var endDateHours = endDate.part('hours'); var startDateMinutes = startDate.part('minutes'); var endDateMinutes = endDate.part('minutes'); // var startDateSeconds = startDate.part('seconds'); // var endDateSeconds = endDate.part('seconds'); var dataArr = []; for (var i = 0; i < days; i++) { var obj = { year: new Date(startMS + dayMS * i ).part('year'), //从开始的时间算起 ,累加天数 ,计算每次累加后的年份 month: new Date(startMS + dayMS * i ).part('month'), //从开始的时间算起 ,累加天数 ,计算每次累加后的月份 day: new Date(startMS + dayMS * i ).part('day'), //从开始的时间算起 ,累加天数 ,计算每次累加后的天数 hour: (function () { //计算请假开始天数的时差 和 结束当天的时差 , 中间的都按8工时算 //i = 0 , 为请假开始 //i = days -1 ,为请假结束 if (i == 0) return getLeaveDate(startDateHours, startDateMinutes); //向下取整请假天数 , 比如1.5天 ,那其中1天就为8工时 (已排除i=0) ,不足一天的做计算具体工时 var date = i < Math.floor(days) ? 8 : getLeaveDate(endDateHours, endDateMinutes); /** * 计算时间差 * @parameter hours * @parameter minutes * return date */ function getLeaveDate(hours, minutes) { //选择的时间, 与公司工作时间计算 // [09:00 - 12:00] [13:00 - 18:00] //在上午工作时效内 if (hours >= 9 && hours <= 12) return hours - 9 + parseFloat((minutes / 60).toFixed(2)); //** 小数太长,保留2位,但会造成精度缺失 //在下午工作时效内 , //上午3个工时 + 下午时差(从13点算起,比如选的是16点,那么时差为3) + 分钟/60 if (hours >= 13 && hours <= 18) return 3 + hours - 13 + parseFloat((minutes / 60).toFixed(2)); //9点前请假 //如果是开始时间,则按8小时算 , 如果是结束时间, 则按0算 if (hours < 9) return i == 0 ? 8 : 0; //超过18点,但未满足1天 //如果是开始时间, 则以0算(请假当天已经上了8小时班) ,反之为8 if (hours > 18) return i == 0 ? 0 : 8; } return date; })(this) }; dataArr.push(obj); } console.log(JSON.stringify(dataArr)); document.getElementById("showText").innerHTML = JSON.stringify(dataArr); // var arr = []; // arr.push([{'year': 2017, 'month': 8, 'day': 2, 'hour': 5}]); // arr.push([{'year': 2017, 'month': 8, 'day': 3, 'hour': 8}]); // arr.push([{'year': 2017, 'month': 8, 'day': 4, 'hour': 8}]); // arr.push([{'year': 2017, 'month': 8, 'day': 5, 'hour': 3}]); } /** 你的 day[0]=[‘year’:2017,‘month’:8,'day' :2,'hour':5] 数组存放有问题 \n 应该先放入对象中,再加入数组 var day = []; var obj = {'year':2017,'month':8 ,'day':2 ,'hour':5}; var obj1 = {'year':2017,'month':8 ,'day':2 ,'hour':5}; ... day.push(obj); day.push(obj2); ... 遍历出来才是你列的数据正确样子 */


 <!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
请假开始时间:<input id="startTime" type="datetime-local"/>
请假结束时间:<input id="endTime" type="datetime-local"/>
<input type="button" onclick="query();" value="查询时间"/>
<div id="showText" style="color: #F00000"></div>


<script>


    /**
     * 将时间格式化 ,补0
     *  2016-6-17  -->  2016-06-17
     *  @param n
     */
    function sup(n) {
        return (n < 10) ? '0' + n : n;
    }


    var Week = ['日', '一', '二', '三', '四', '五', '六'];
    /**
     * 获取时间分散值
     * 年、月、日、周、时、分、秒 等
     * @param key  匹配的片段值
     */
    Date.prototype.part = function (key) {

        switch (key) {
            case 'year' :
                return this.getFullYear();
            case 'month' :
                return sup(this.getMonth() + 1);
            case 'day' :
                return sup(this.getDate());
           case 'week' :
                return Week[this.getDay()];
            case 'wy' :
                return this.WeekNumOfYear();
            case 'hours' :
                return sup(this.getHours());
            case 'minutes' :
                return sup(this.getMinutes());
            case 'seconds' :
                return this.getSeconds();
            default :
                return "";
        }
    };
    //YYYY-MM-DD HH:mm:ss
    Date.prototype.toLocaleString = function () {
        return this.getFullYear() + "-" + (this.getMonth() + 1) + "-" + this.getDate() + " " + this.getHours() + ":" + this.getMinutes() + ":" + this.getSeconds();
    };

    function query() {



        //获取选择的开始时间和结束时间
        var startValue = document.getElementById('startTime').value;
        var endValue = document.getElementById('endTime').value;
        if (startValue == "") {
            return alert("请选择开始时间");
        }
        if (endValue == "") {
            return alert("请选择结束时间");
        }
        var startDate = new Date(startValue);
        var endDate = new Date(endValue);

        //除去带T时间格式
        startDate = new Date(startDate.toISOString().replace(/T/g, ' ').replace(/\.[\d]{3}Z/, ''));
        endDate = new Date(endDate.toISOString().replace(/T/g, ' ').replace(/\.[\d]{3}Z/, ''));

        var startMS = startDate.getTime();
        var endMS = endDate.getTime();

        if (startMS - endMS >= 0)
            return alert("开始时间不能小于结束时间 或 与结束时间相同");


        var dayMS = 1000 * 60 * 60 * 24;//毫秒 *1000 *60 *60 *24 = 天数
        //获取天差
        var days = (endMS - startMS) / dayMS;

        //获取开始时间和结束时候的年份、月份、日期 小时
//      var startDateYear = startDate.part('year');
//      var endDateYear = endDate.part('year');
//
//      var startDateMonth = startDate.part('month');
//      var endDateMonth = endDate.part('month');
//
//      var startDateDay = startDate.part('day');
//      var endDateDay = endDate.part('day');

        var startDateHours = startDate.part('hours');
        var endDateHours = endDate.part('hours');

        var startDateMinutes = startDate.part('minutes');
        var endDateMinutes = endDate.part('minutes');

//      var startDateSeconds = startDate.part('seconds');
//      var endDateSeconds = endDate.part('seconds');


        var dataArr = [];
        for (var i = 0; i < days; i++) {

            var obj = {
                year: new Date(startMS + dayMS * i ).part('year'),  //从开始的时间算起 ,累加天数 ,计算每次累加后的年份
                month: new Date(startMS + dayMS * i ).part('month'),  //从开始的时间算起 ,累加天数 ,计算每次累加后的月份
                day: new Date(startMS + dayMS * i ).part('day'),   //从开始的时间算起 ,累加天数 ,计算每次累加后的天数
                hour: (function () {

                    //计算请假开始天数的时差 和 结束当天的时差 , 中间的都按8工时算
                    //i = 0 , 为请假开始
                    //i = days -1 ,为请假结束
                    if (i == 0)
                        return getLeaveDate(startDateHours, startDateMinutes);

                    //向下取整请假天数 , 比如1.5天  ,那其中1天就为8工时 (已排除i=0) ,不足一天的做计算具体工时
                    var date = i < Math.floor(days) ? 8 : getLeaveDate(endDateHours, endDateMinutes);

                    /**
                     *  计算时间差
                     *  @parameter hours
                     *  @parameter minutes
                     *  return date
                     */
                    function getLeaveDate(hours, minutes) {

                        //选择的时间, 与公司工作时间计算
                        // [09:00 - 12:00] [13:00 - 18:00]
                        //在上午工作时效内
                        if (hours >= 9 && hours <= 12)
                            return hours - 9 + parseFloat((minutes / 60).toFixed(2));  //** 小数太长,保留2位,但会造成精度缺失


                        //在下午工作时效内 ,
                        //上午3个工时 + 下午时差(从13点算起,比如选的是16点,那么时差为3) + 分钟/60
                       if (hours >= 13 && hours <= 18)
                            return 3 + hours - 13 + parseFloat((minutes / 60).toFixed(2));


                        //9点前请假
                        //如果是开始时间,则按8小时算 , 如果是结束时间, 则按0算
                        if (hours < 9)
                            return i == 0 ? 8 : 0;


                        //超过18点,但未满足1天
                        //如果是开始时间, 则以0算(请假当天已经上了8小时班) ,反之为8
                        if (hours > 18)
                            return i == 0 ? 0 : 8;

                    }

                    return date;
                })(this)
            };

            dataArr.push(obj);
        }

        console.log(JSON.stringify(dataArr));
        document.getElementById("showText").innerHTML = JSON.stringify(dataArr);

//        var arr = [];
//        arr.push([{'year': 2017, 'month': 8, 'day': 2, 'hour': 5}]);
//        arr.push([{'year': 2017, 'month': 8, 'day': 3, 'hour': 8}]);
//        arr.push([{'year': 2017, 'month': 8, 'day': 4, 'hour': 8}]);
//        arr.push([{'year': 2017, 'month': 8, 'day': 5, 'hour': 3}]);


    }


    /**
     你的 day[0]=[‘year’:2017,‘month’:8,'day' :2,'hour':5]  数组存放有问题 \n
     应该先放入对象中,再加入数组
     var day = [];
     var obj  =  {'year':2017,'month':8 ,'day':2 ,'hour':5};
     var obj1  =  {'year':2017,'month':8 ,'day':2 ,'hour':5};
     ...
     day.push(obj);
     day.push(obj2);
     ...
     遍历出来才是你列的数据正确样子
     */

</script>
</body>
</html>

取日期问题有修复了, 调整了取值逻辑.

 <!DOCTYPE html>
<html>
<head>
    <meta charset="GBK">
    <title></title>
</head>
<body>
请假开始时间:<input id="startTime" type="datetime-local"/>
请假结束时间:<input id="endTime" type="datetime-local"/>
<input type="button" onclick="query();" value="查询请假工时"/>
<div id="showText" style="color: #F00000"></div>


<script>


    /**
     * 将时间格式化 ,补0
     *  2016-6-17  -->  2016-06-17
     *  @param n
     */
    function sup(n) {
        return (n < 10) ? '0' + n : n;
    }


    var Week = ['日', '一', '二', '三', '四', '五', '六'];
    /**
     * 获取时间分散值
     * 年、月、日、周、时、分、秒 等
     * @param key  匹配的片段值
     */
    Date.prototype.part = function (key) {

        switch (key) {
            case 'year' :
                return this.getFullYear();
            case 'month' :
                return sup(this.getMonth() + 1);
            case 'day' :
                return sup(this.getDate());
            case 'week' :
                return Week[this.getDay()];
            case 'wy' :
                return this.WeekNumOfYear();
            case 'hours' :
                return sup(this.getHours());
            case 'minutes' :
                return sup(this.getMinutes());
            case 'seconds' :
                return this.getSeconds();
            default :
                return "";
        }
    };


    /**
     * 小数太长,保留2位,但会造成精度缺失
     */
    function formatHours(m) {
        return m.toFixed(2);
    }


    function query() {


        //获取选择的开始时间和结束时间
        var startValue = document.getElementById('startTime').value;
        var endValue = document.getElementById('endTime').value;
        if (startValue == "") {
            return alert("请选择开始时间");
        }
        if (endValue == "") {
            return alert("请选择结束时间");
        }
        var startDate = new Date(startValue);
        var endDate = new Date(endValue);

        //除去带T时间格式
        startDate = new Date(startDate.toISOString().replace(/T/g, ' ').replace(/\.[\d]{3}Z/, ''));
        endDate = new Date(endDate.toISOString().replace(/T/g, ' ').replace(/\.[\d]{3}Z/, ''));

        var startMS = startDate.getTime();
        var endMS = endDate.getTime();

        if (startMS - endMS >= 0)
            return alert("开始时间不能小于结束时间 或 与结束时间相同");


        var dayMS = 1000 * 60 * 60 * 24;//毫秒 *1000 *60 *60 *24 = 天数


        //获取开始时间和结束时候的年份、月份、日期 小时
//        var startDateYear = parseInt(startDate.part('year'));
//        var endDateYear = parseInt(endDate.part('year'));

//        var startDateMonth = parseInt(startDate.part('month'));
//        var endDateMonth = parseInt(endDate.part('month'));

//        var startDateDay = parseInt(startDate.part('day'));
//        var endDateDay = parseInt(endDate.part('day'));

        var startDateHours = parseInt(startDate.part('hours'));
        var endDateHours = parseInt(endDate.part('hours'));

        var startDateMinutes = parseInt(startDate.part('minutes'));
        var endDateMinutes = parseInt(endDate.part('minutes'));

//        var startDateSeconds = startDate.part('seconds');
//        var endDateSeconds = endDate.part('seconds');

        var days = (function () {
            //两个时间相差天数 yyyy-dd-mm 字符串
            function datedifference(sDate1, sDate2) {
                var dateSpan;
                dateSpan = Date.parse(sDate1) - Date.parse(sDate2);
                dateSpan = Math.abs(dateSpan);
                return (dateSpan / dayMS) + 1
            }

            return datedifference(startValue.substring(0, 10), endValue.substring(0, 10));
        })();


        //console.log("天数差 : " + days);
        var dataArr = [];
        for (var i = 0; i < days; i++) {

            var obj = {
                year: new Date(startMS + dayMS * i).part('year'),  //从开始的时间算起 ,累加天数 ,计算每次累加后的年份
                month: new Date(startMS + dayMS * i).part('month'),  //从开始的时间算起 ,累加天数 ,计算每次累加后的月份
                day: new Date(startMS + dayMS * i).part('day'),   //从开始的时间算起 ,累加天数 ,计算每次累加后的天数
                hour: (function () {

                    //重置标记时间 , 防止时间范围溢出
                    validateScope();

                    //计算请假开始天数的时差 和 结束当天的时差 , 中间的都按8工时算
                    //i = 0 , 为请假开始
                    //i = days -1 ,为请假结束
                    if (i == 0) {
                        //特殊情况, 只请当天假
                        if (startValue.substring(0, 10) == endValue.substring(0, 10)) {
                            return (function () {

                                //开始时间比结束时间大
                                if (startDateHours * 60 + startDateMinutes > endDateHours * 60 + endDateMinutes)
                                    return alert("时间选择不正确,请重新选择!");

                                //结束时间不到9点有效时间 , 直接返回0
                                if (endDateHours < 9 || (endDateHours == 9 && endDateMinutes == 0))
                                    return 0;

                                //开始和结束时间  小时:分钟  都转成分钟计算
                                var startTimeToMinutes = getEffectiveMinutes(startDateHours, startDateMinutes);
                                var endTimeToMinutes = getEffectiveMinutes(endDateHours, endDateMinutes);


                                /**
                                 * 获取有效时间,转换成分钟
                                 * @param hours
                                 * @param minutes
                                 * return
                                 */
                                function getEffectiveMinutes(hours, minutes) {
                                    var hoursToMinutes;

                                    //计算结束时间有效时间9~18时,  需要减去12~13中无效时间
                                    if (hours < 12 || (hours * 60 + minutes == 12 * 60))
                                        hoursToMinutes = hours * 60 + minutes;  //[00:00,12:00] 范围的时间总分钟
                                    else if (hours >= 13)
                                        hoursToMinutes = hours * 60 + minutes - 60;  //下午有效时段,(12:00~13:00) 60分钟无效 ,如果开始时间超过12点,那也会算入无效时间
                                    else
                                        hoursToMinutes = 12 * 60;    //(12:00 , 13:00) ,都以12个小时计算

                                    return hoursToMinutes;
                                }

                                //计算时差之请假工时
                                return formatHours((endTimeToMinutes - startTimeToMinutes) / 60);

                            })(this);
                        }
                        else
                            return getLeaveDate(startDateHours, startDateMinutes);
                    }

                    //排除请假当天和结束当天,中途的所有天数以8个工时计算
                    var date = i < days - 1 ? 8 : getLeaveDate(endDateHours, endDateMinutes);

                    /**
                     *  计算时间差
                     *
                     *  @parameter hours
                     *  @parameter minutes
                     *  return date
                     */
                    function getLeaveDate(hours, minutes) {
                        minutes = parseInt(minutes);
                        //去除特殊边线值
                        if (minutes == 0 && hours == 9)   //(0 ,9] 小于9点的和整9点的,不算迟到 ,< 9被重置为09:00
                        //如果是开始时间,则按8小时算 , 如果是结束时间, 则按0算
                            return i == 0 ? 8 : 0;

                        //计算结束时间有效时间9~18时,  需要减去12~13中无效时间
                        if (hours < 12 || (hours * 60 + minutes == 12 * 60)) {
                            if (i == 0)  //全天8小时有效 ,hours值包含0点到9点无效 ,算法获取有效工时
                                return 8 - (hours - 9) - parseFloat(formatHours(minutes / 60));
                            return hours - 9 + parseFloat(formatHours(minutes / 60));
                        } else if (hours >= 13) {
                            if (i == 0) //全天8小时有效 ,hours值包含0点到9点无效 ,中午1小时无效 ,算法获取有效工时
                                return 8 - (hours - 9 - 1) - parseFloat(formatHours(minutes / 60));
                            return hours - 9 - 1 + parseFloat(formatHours(minutes / 60));
                        } else
                            return i == 0 ? 5 : 3;

                    }

                    return date;

                })(this)
            };

            dataArr.push(obj);
        }


        /**
         * 校验时间值有效范围 ,如果超有效范围,自动重置默认
         * @param endDateHours  结束的小时
         * @param endDateMinutes 结束的分钟
         * @param startDateHours 开始的小时
         * @param endDateHours 开始的分钟
         */
        function validateScope() {

            //请假结束时间大于18时, 以18计算
            if (endDateHours > 18 || (endDateHours == 18 && endDateMinutes >= 0)) {
                endDateHours = 18;
                endDateMinutes = 0;

            }

            //请假开始时间小于9小时, 且结束时间大于9小时 ,有效时间从9点开始算起
            if (startDateHours < 9 && (endDateHours * 60 + endDateMinutes) > 9 * 60) {
                startDateHours = 9;
                startDateMinutes = 0;

            }

            //请假时间大于18点
            if (startDateHours >= 18) {
                startDateHours = 18;
                startDateMinutes = 0;
            }

            //结束小于9点
            if (endDateHours < 9) {
                endDateHours = 9;
                endDateMinutes = 0;
            }

        }


        //console.log(JSON.stringify(dataArr));
        document.getElementById("showText").innerHTML = JSON.stringify(dataArr);


    }

</script>
</body>
</html>