js 将一大段时间均分为很多个小时间段
最近写项目,遇到一个将选中时间段平均分割为若干小段,然后根据小段时间在数据库查询求均值的问题,后台大哥犯懒,非说后台做不了,让我分好传给他ヾ(。 ̄□ ̄)ツ゜゜゜好气呦,但还要保持微笑,我就是这么懂礼貌的好孩子ー( ̄~ ̄)ξ
闲话不多说,来说实现过程
最开始只是分固定时间段,每天两小时一分,也就直接全写了,后来需求变了,日期选择输入,想要多少天就要多少天,时间大了要求取到的数据量还是那么多
我:不太好实现啊老板
boss:啥?别人都能做到,你咋就做不到?你这技术水平怕是有点低了把?
我:那我试试(MDZZ)
先确定后台需要什么数据格式,按照存入格式,先写个方法
1 function range(beginTime, endTime) {//存入格式 2 this.beginTime = beginTime; 3 this.endTime = endTime; 4 }
考虑到这是一个js文件,数据分割也是固定的等分,就写一个从外部获取参数的函数吧,TimeRange(startTime,endTime)函数用来供页面调用,只传入开始时间,结束时间,不写分多少组了,因为需要的数据总量一般都是固定的,分多少组也是固定的,哪里需要直接来js改就好了
1 function TimeRange(startTime, endTime) { //传入开始时间var startTime 传入结束时间var endTime 传入格式xxxx-xx-xx 年月日 2 var amount = 100; //定义分多少组 3 var startTimes = startTime + " 00:00:00"; //日期添加时分秒 开始日期 4 var endTimes = endTime + " 23:59:59"; //日期添加时分秒 结束日期 5 }
判断一波
1 if(endTimes <= startTimes) { 2 alert('结束日期必须大于开始日期!'); 3 return -1; 4 } 5 6 if(dataDiff > 15) { 7 alert('单次查询日期不超过两周,请重新选择!'); 8 return -2; 9 }
既然平均分,那就得知道时间间隔,计算时间间隔,写个方法直接调用
1 //计算天数差的函数,通用 2 function DateDiff(sDate1, sDate2) { //sDate1和sDate2是2006-12-18格式 3 var aDate, oDate1, oDate2, iDays 4 aDate = sDate1.split("-") 5 oDate1 = new Date(aDate[1] + '-' + aDate[2] + '-' + aDate[0]) //转换为12-18-2006格式 6 aDate = sDate2.split("-") 7 oDate2 = new Date(aDate[1] + '-' + aDate[2] + '-' + aDate[0]) 8 iDays = parseInt(Math.abs(oDate1 - oDate2) / 1000 / 60 / 60 / 24) //把相差的毫秒数转换为天数 9 return iDays 10 }
整理了一下逻辑,伪代码如下
1 //计算时间段总时间,分割后每段时间间隔,单位(秒) 2 var timeRange;//存储计算出的时间段 3 var timeAll ; //总时间间隔 4 var timeGap ; //分割后时间间隔 5 var slidingTime = 0; //循环开始条件 6 var momentTime_front; //时间段前一个值 7 var momentTime_rear;//时间段后一个值 8 for(slidingTime; slidingTime < timeAll; slidingTime += timeGap) { 9 momentTime_front = 计算出的时间前半部分 10 momentTime_rear = 计算出的时间后半部分 11 timeRange.push(new range(momentTime_front, momentTime_rear));//将计算后的小段的开始时间和结束时间组合存入timeRange 12 } 13 return timeRange; 14 }
实现后的TimeRange()方法如下:
1 function TimeRange(startTime, endTime) { //传入开始时间var startTime 传入结束时间var endTime 2 var amount = 100; //定义分多少组 3 var timeRange = new Array(); //return数组初始化 4 var dataDiff = DateDiff(startTime, endTime); //计算两个日期相差天数 5 var startTimes = startTime + " 00:00:00"; //日期添加时分秒 开始日期 6 var endTimes = endTime + " 23:59:59"; //日期添加时分秒 结束日期 7 8 if(endTimes <= startTimes) { 9 alert('结束日期必须大于开始日期!'); 10 return -1; 11 } 12 13 if(dataDiff > 15) { 14 alert('单次查询日期不超过两周,请重新选择!'); 15 return -2; 16 } 17 if(1) { 18 //计算时间段总时间,分割后每段时间间隔,单位(秒) 19 var timeAll = (dataDiff + 1) * 24 * 3600; //总时间间隔 20 var timeGap = timeAll / amount; //分割后时间间隔 21 var slidingTime = 0; //循环开始 22 var momentTime_front; 23 var momentTime_rear; 24 for(slidingTime; slidingTime < timeAll; slidingTime += timeGap) { 25 momentTime_front = addDatetime(startTimes, slidingTime) 26 momentTime_rear = addDatetime(startTimes, (slidingTime + timeGap - 1)) 28 timeRange.push(new range(momentTime_front, momentTime_rear)); 29 } 30 return timeRange; 31 } 32 }
接下来的问题就是如何计算 momentTime_front 和 momentTime_rear 了
我的思路是将开始时间加上秒数转换后的日时分秒等再相加,直接添加的语句或者方法没找到,那咋办?还把我难住了?找不到算了,技不如人,不如自己写一个方法,直接计算两个字符串类型的时间格式相加,哼╭(╯^╰)╮
先想想怎么写,需要现将字符串转换成字符串类型的数组,将年月日时分秒都分开才能逐个击破,分开后的数组都是字符串类型,没法进行加减运算,强转!先写个将日期类型转换为整型数组的方法
1 //传入'1970-01-01 00:00:00' 将其分成可计算的整形数组[1970,1,1,0,0,0] 2 function getArray(dataTime) { 3 dataTime = dataTime.replace(/ /, "-") 4 var timesArray = dataTime.split("-"); 5 var timeArray = timesArray[3].split(":"); 6 timesArray[0] = parseInt(timesArray[0]); 7 timesArray[1] = parseInt(timesArray[1]); 8 timesArray[2] = parseInt(timesArray[2]); 9 timesArray[3] = parseInt(timeArray[0]); 10 timesArray[4] = parseInt(timeArray[1]); 11 timesArray[5] = parseInt(timeArray[2]); 12 return timesArray; 13 }
ok,能计算了,但是增加的时间是秒,还得把秒转换成年月日时分秒格式
1 //将秒转换为日期格式(最高到天) 2 function getDatetime(s) { 3 var dataTime = new Array; 4 //存入 秒 5 dataTime[5] = parseInt((s / 1) % 60); 6 //存入 分 7 dataTime[4] = parseInt((s / 60) % 60); 8 //存入 时 9 dataTime[3] = parseInt((s / 60 / 60) % 24); 10 //存入 日 11 dataTime[2] = parseInt(s / 60 / 60 / 24); 12 //存入 月 13 dataTime[1] = parseInt(0); 14 //存入 年 15 dataTime[0] = parseInt(0); 16 return dataTime; 17 }
好嘞,需要的类有了,可是时间相加,不是简单的数字相加啊,还要考虑闰年问题,大月小月问题,嗯....计算大月小月
1 //获取当月天数 2 function getMonthDay(years, month) { 3 switch(month) { 4 case "2": 5 if(years % 4 == 0 && years %100 !=0) { 6 return "29"; 7 } 8 if(years % 4 == 0 &&years % 100 == 0 && years % 400 == 0) { 9 return "29"; 10 } else { 11 return "28"; 12 } 13 return "28"; 14 case "4": 15 return "30"; 16 case "6": 17 return "30"; 18 case "9": 19 return "30"; 20 case "11": 21 return "30"; 22 default: 23 return "31"; 24 } 25 }
因为生成的结果是个数组,我们认识,但是计算机傻呀,还要在转换为输入的日期格式的字符串,逆向的过程
1 //将datetime日期数组转换为string类型 2 function dataTimetoString(dateTime) { 3 for(i = 0; i <= 5; i++) { 4 dateTime[i] = dateTime[i].toString(); 5 } 6 var dataTime_Str = ""; 7 //添加 年 8 dataTime_Str += dateTime[0] + "-"; 9 //添加 月 10 if(dateTime[1].length == 2) { 11 dataTime_Str += dateTime[1] + "-"; 12 } else { 13 dataTime_Str += "0" + dateTime[1] + "-"; 14 } 15 //添加 日 16 if(dateTime[2].length == 2) { 17 dataTime_Str += dateTime[2] + " "; 18 } else { 19 dataTime_Str += "0" + dateTime[2] + " "; 20 } 21 //添加 时 22 if(dateTime[3].length == 2) { 23 dataTime_Str += dateTime[3] + ":"; 24 } else { 25 dataTime_Str += "0" + dateTime[3] + ":"; 26 } 27 //添加 分 28 if(dateTime[4].length == 2) { 29 dataTime_Str += dateTime[4] + ":"; 30 } else { 31 dataTime_Str += "0" + dateTime[4] + ":"; 32 } 33 //添加 秒 34 if(dateTime[5].length == 2) { 35 dataTime_Str += dateTime[5]; 36 } else { 37 dataTime_Str += "0" + dateTime[5]; 38 } 39 return dataTime_Str; 40 }
好啦,准备工作全部完成,开始我们核心的增加的计算啦,各种小细节问题,想起来就头疼,好在解决了,不细说啦,Showtime! ヾ(≧O≦)〃嗷~ヾ
1 //将两个日期相加后的结果返回 2 function addDatetime(dt, s) { 3 var dateTime = new Array; //创建数组 4 var addDatetime = new Array; //创建数组 5 var dataTimeStr = new Array; //创建数组 6 dateTime = getArray(dt); //将字符串类型的时间转换为整形数组 7 addDatetime = getDatetime(s); //将间隔时间秒转换为日期格式的整形数组 8 var count = 0;//存储进位 9 10 dataTimeStr[5] = (dateTime[5] + addDatetime[5] + count) % 60; //秒 11 ((dateTime[5] + addDatetime[5] + count) > 59) ? count = 1: count = 0; 12 13 dataTimeStr[4] = (dateTime[4] + addDatetime[4] + count) % 60; //分 14 ((dateTime[4] + addDatetime[4] + count) > 59) ? count = 1: count = 0; 15 16 dataTimeStr[3] = (dateTime[3] + addDatetime[3] + count) % 24; //时 17 ((dateTime[3] + addDatetime[3] + count) > 23) ? count = 1: count = 0; 18 19 var m = getMonthDay(dateTime[0].toString(), dateTime[1].toString()); 20 dataTimeStr[2] = (dateTime[2] + addDatetime[2] + count) % m; //日 21 ((dateTime[2] + addDatetime[2] + count) > m) ? count = 1: count = 0; 22 if(dataTimeStr[2] == 0) { 23 dataTimeStr[2] = (dateTime[2] + addDatetime[2] + count) % (m + 1); 24 count = 0; 25 } 26 dataTimeStr[1] = (dateTime[1] + addDatetime[1] + count) % 12; //月 27 ((dateTime[1] + addDatetime[1] + count) > 12) ? count = 1: count = 0; 28 if(dataTimeStr[1] == 0) { 29 dataTimeStr[1] = (dateTime[1] + addDatetime[1] + count) % 13; 30 count = 0; 31 } 32 33 dataTimeStr[0] = (dateTime[0] + addDatetime[0] + count) / 1; //年 34 35 var dataTime_str = dataTimetoString(dataTimeStr); //将日期格式的数组转换为字符串 36 return dataTime_str; 37 }
如果有错误,麻烦评论区告诉我一声,万分感谢,觉得有帮助的点个赞谢谢,撒油那啦...ヾ( ̄▽ ̄)Bye~Bye~
做了修改,新的链接贴上来,超简单,感谢评论
http://www.cnblogs.com/xichuanggushi/p/7851979.html