计算请假天数,笼统来说就是计算两个日期的差值。对于JS来说,两个时间直接相减,得到的是这两个时间差的毫秒数。

先上代码后贴图。

1.测试数据

后文中用到的测试数据如下:

var dateStart = '2018-12-01 04:15',

dateEnd= '2018-12-08 12:15';

var MS_HOUR = 1000*60*60;

2.时间差毫秒数

普通计算两个时间差的方法如下:

functiongetDiff(start, end)

{var s =Date.parse(start),

e=Date.parse(end);//取绝对值

return Math.abs(e -s);

}console.log(getDiff(dateStart, dateEnd));

输出:633600000

3.时间差小时数

计算两个时间差的小时数:

functiongetDiffByHour(start, end)

{/****

* start:请假开始时间

* end:请假结束时间

* 计算小时数(1位小数)

* ***/

var s =Date.parse(start),

e=Date.parse(end);//取绝对值

var diff = Math.abs(e -s);return (diff / (1000 * 60 * 60)).toFixed(1);

}

console.log(getDiffByHour(dateStart, dateEnd));

输出:176.0

4.简单请假规则

不同单位对请假的限制条件不同,现规定请假天数计算规则如下:

1、请假半天记0.5天;

2、小于半天部分,1小时计0.1天,2小时计0.2天,以此类推

那么计算逻辑也还比较简单:

functiongetDiffByDay(start, end)

{/****

* start:请假开始时间

* end:请假结束时间

* 计算天数,半天按0.5天计算,小于半天,1小时计0.1天,2小时计0.2天,3小时计0.3天,4小时计0.4天(1位小数)

* ***/

var s =Date.parse(start),

e=Date.parse(end);//取绝对值

var diff = Math.abs(e -s);var result = 0,

hour= Math.floor(diff / (1000 * 60 * 60)),

day= Math.floor(diff / (1000 * 60 * 60 * 24));

result=day;if (day > 0)

{//去掉天数部分,仅留小时数

hour -= day * 24;

}if (hour > 5)

{//如果大于半天(5小时)

result += 0.5;

hour= Math.floor((diff - (day * 24 + 5) * 1000 * 60 * 60) / (1000 * 60 * 60));

}if (hour > 1)

{

result+= hour * 0.1;

}returnresult;

}

console.log(getDiffByDay(dateStart, dateEnd));

输出:7.8

5.复杂请假规则

倘若规定上下班时间,中午休息时间,工作时长等等,那计算的逻辑就相当复杂了。

现规定上下班及午休时间如下:

上班时间:8:00

下班时间:18:00

午休时间:12:00-14:00

(正常日工作时长:8小时)

那么,请假1小时则为1/8天,4小时即为0.5天。

简单分析:

1.请假时段在同一天内,直接计算;

2.请假时段跨越了多天的情况,我们可以把请假时间分成两个部分,请假时间 start 至 end,可以看成第一部分: start的时间起到第二天 end时间止的请假时长,第二部分:start日期与end日期之间的天数(不含start和end)。

例如:请假时段 ‘2018-01-01 8:00’ 至 '2018-01-03 12:00',那么请假时长可以分为 '2018-01-01 8:00'至'2018-01-02 12:00'的时长(过滤闲暇时间和午休时间),和'2018-01-01'至'2018-01-03'间的天数,即为 1.5+1=2.5天。

5.1 请假时间在同一个日期

这种情况下,直接是end-start然后除去午休时间,最后得到的小时数来计算天数。

functiongetLeaveDayInOneDay(start, end, wt)

{/**

* 获取一天内的请假天数

* @start:起始时间

* @end:截止时间

* @wt:作息时间,包含上下班时间和午休时间

**/

var diff ={ };

diff.d= 0;/**

* diff:

* {

* d:天数

* h:小时数

* st:起始时间毫秒数

* et:截止时间毫秒数

* }

**/

try{var startInt =Date.parse(start),

endInt=Date.parse(end);if (startInt <= wt.on && wt.off <=endInt)

{//全天

diff.d = 1.0;

}else if (startInt <= wt.on && wt.noonOn <= endInt && endInt <=wt.noonOff)

{//上半天

diff.d = 0.5;

}else if (wt.noonOn <= startInt && startInt <= wt.noonOff && wt.off <=endInt)

{//下半天

diff.d = 0.5;

}else{//去除极端情况,确保请假时间在工作时间内

diff.st = Math.max(wt.on, startInt); //取上班时间内

diff.st = diff.st <= wt.noonOn ? diff.st : (wt.noonOff <= diff.st ?diff.st : wt.noonOff && wt.on != endInt);

diff.st= Math.min(diff.st, wt.off); //取下班时间内

diff.et=Math.max(diff.st, endInt);

diff.et=Math.min(diff.et, wt.off);

diff.et= diff.et <= wt.noonOn ? diff.et : (wt.noonOff <= diff.et ?diff.et : wt.noonOn && startInt != wt.off);

diff.et=Math.max(wt.on, diff.et);

diff.diff= diff.et -diff.st;if (diff.st <= wt.noonOn && wt.noonOff <=diff.et)

{//去除午休时段

diff.diff = diff.diff - (wt.noonOff -wt.noonOn);

}

diff.h= diff.diff /MS_HOUR;//TODO:根据小时数计算天数

diff.d +=getLeaveByHour(diff.h, wt.wh);

}

}catch(e)

{this.log("计算【" + start + "】到【" + end + "】期间的请假天数发生异常:" +e.message);

}returndiff.d;

};

5.2 请假时间跨越多个日期

计算第一部分的时长:

functiongetLeaveDaysInTwoDay(start, end, wtObjStr)

{/**

* 获取start到第二天end时间内的请假时长

* @start:起始时间

* @end:截止时间

* @wtObjStr:作息时间,包含上下班时间和午休时间

* {

* wh:日工作时长,整型,如8

* on:上班时间,字符串,如'09:00'

* off:下班时间,字符串,如'18:00'

* noonOn:中午开始时间,字符串,如'12:00'

* noonOff:中午结束时间,字符串,如'14:00'

* }

* 值得注意的是,如果未设置作息时间,则上班时间为00:00,下班时间为23:59,中午时间均为下班时间,这个应该在setWorkTime中进行设置

**/

var wt ={ },

_date= '2019-01-08',

_date2= '2019-01-09';var start = Date.parse(_date + ' ' + start.Format('hh:mm:ss')),

end= Date.parse(_date2 + ' ' + end.Format('hh:mm:ss'));

wt.wh=wtObjStr.wh;

wt.on= Date.parse(_date + ' ' +wtObjStr.on);

wt.off= Date.parse(_date + ' ' +wtObjStr.off);

wt.noonOn= Date.parse(_date + ' ' +wtObjStr.noonOn);

wt.noonOff= Date.parse(_date + ' ' +wtObjStr.noonOff);

wt.on2= Date.parse(_date2 + ' ' +wtObjStr.on);

wt.off2= Date.parse(_date2 + ' ' +wtObjStr.off);

wt.noonOn2= Date.parse(_date2 + ' ' +wtObjStr.noonOn);

wt.noonOff2= Date.parse(_date2 + ' ' +wtObjStr.noonOff);var diff = 0;

start=Math.max(start, wt.on);

start= start <= wt.noonOn ? start : (wt.noonOff < start ?start : wt.noonOff);

start=Math.min(start, wt.off);

end=Math.max(end, wt.on2);

end= end <= wt.noonOn2 ? end : (wt.noonOff2 < end ?end : wt.noonOn2);

end=Math.min(end, wt.off2);

diff= wt.off -start;if (start <= wt.noonOn) diff -= (wt.noonOff -wt.noonOn);

diff+= (end -wt.on2);if (end >= wt.noonOff2) diff -= (wt.noonOff2 -wt.noonOn2);return getLeaveByHour(diff /MS_HOUR, wt.wh);

};

再来看第二部分,先笼统计算一下天数:

functiongetDaysOfPeriod(start, end)

{/**

* 获取一段时期内的天数,包含起止日期

* @start:起始时间

* @end:截止时间

**/

try{var startObj ={'y': start.getFullYear(),'m': start.getMonth() + 1,'d': start.getDate()

},

endObj={'y': end.getFullYear(),'m': end.getMonth() + 1,'d': end.getDate()

};//start和end必须包含,所以需要+1

var startPart = start.getTotalDaysOfMonth() - startObj.d + 1,

monthPart= 0,

endPart=endObj.d;if (startObj.y !=endObj.y)

{//跨年的情况

var startMonths = 12 - startObj.m; //获取start年份中剩下的月份数

for (var i = startObj.m + 1; i <= startObj.m + startMonths; i++)

{

monthPart+= (new Date(startObj.y, i - 1, 1)).getTotalDaysOfMonth();

}for (var i = 1; i <= endObj.m - 1; i++)

{

monthPart+= (new Date(endObj.y, i - 1, 1)).getTotalDaysOfMonth();

}

}else{if (startObj.m !=endObj.m)

{//跨月

for (var i = startObj.m + 1; i < endObj.m; i++)

{

monthPart+= (new Date(startObj.y, i - 1, 1)).getTotalDaysOfMonth();

}

}else{

startPart= 0;

endPart= endObj.d - startObj.d + 1;

}

}this.log("【" + start + "】到【" + end + "】期间的天数:" + (startPart + monthPart +endPart));return startPart + monthPart +endPart;

}catch(e) {this.log("计算【" + start + "】到【" + end + "】期间的天数发生异常:" +e.message);return 0;

}

};

这个天数除去起止日期即为第二部分。

主函数如下:

functiongetLeaveDays(start, end)

{/**

* 获取一段时间内的请假天数,包含上下班时间和午休时间

* @start:起始时间

* @end:截止时间

**/

var startInt =Date.parse(start),

endInt=Date.parse(end),

startObj={'y': start.getFullYear(),'m': start.getMonth() + 1,'d': start.getDate(),'h': start.getHours(),'mi': start.getMinutes()

},

endObj={'y': end.getFullYear(),'m': end.getMonth() + 1,'d': end.getDate(),'h': end.getHours(),'mi': end.getMinutes()

};var diff = 0,wt ={ },

_date= start.Format('yyyy-MM-dd');

wt.wh= this._work.wh;

wt.on= Date.parse(_date + ' ' + this._work.on);

wt.off= Date.parse(_date + ' ' + this._work.off);

wt.noonOn= Date.parse(_date + ' ' + this._work.noonOn);

wt.noonOff= Date.parse(_date + ' ' + this._work.noonOff);//请假起止时间不在同一日期

if(startObj.y !== endObj.y || startObj.m !== endObj.m || startObj.d !==endObj.d) {var days = getDaysOfPeriod(start, end);/**

* days包含start和end,days>=2,所以请假时间可以按两个部分计算:

* start那天到第二天end时间的请假时长+start和end中间天数*/

if (days < 2)

{this.log('计算一段时间内(非同一天)的天数不能少于2');return 0;

}

diff+= days - 2;

diff+= getLeaveDaysInTwoDay(start, end, this._work);

}else { //请假起止时间在同一日期内

diff =getLeaveDayInOneDay(start, end, wt);

}returndiff;

};

functiongetLeaveByHour(hour, workLen)

{var diff = 0;var dv = Math.floor(hour /workLen);if (dv >= 1)

{

diff+=dv;

hour-= dv *workLen;

}if (hour >= workLen / 2)

{

diff+= 0.5;

hour-= workLen / 2;

}if (hour >= 1)

{

diff+= parseFloat((hour / workLen).toFixed(1));

}returndiff;

};

再贴上测试效果吧:

当然,小数点后面的四舍五入的处理就看各自的情况了。

花了点时间整理封装了下,不知道怎么上传附件,有需要源码的可以留言。

对于请假天数的计算就写这么些了,不同场景肯定有不同的需求,以上算法只是抛砖引玉,更多的还需要自行修改,你也可以留言一起学习。

小菜一枚,大神路过请多多指教,诚谢。

转发请注明出处。

最后编辑时间:2019-01-10

mysql 统计请假天数_Javascript 计算请假天数相关推荐

  1. mysql 连续天数_mysql计算连续天数,mysql连续登录天数,连续天数统计

    mysql计算连续天数,mysql连续登录天数,连续天数统计 >>>>>>>>>>>>>>>>>& ...

  2. 【泛微表单】请假流程中计算请假时长(非系统自带考勤类型)

    请假流程计算请假时长 按一天8小时计算,日期为浏览按钮日期字段,时间为单选下拉框: <script> var beginTimeId = {id: "field22286&quo ...

  3. Javascript 计算请假天数

    计算请假天数,笼统来说就是计算两个日期的差值.对于JS来说,两个时间直接相减,得到的是这两个时间差的毫秒数. 先上代码后贴图. 1.测试数据 后文中用到的测试数据如下: var dateStart = ...

  4. 计算请假天数JavaScript方法

    计算请假天数JavaScript方法 前言 最近,有这么个需求,给用户做个请假审批系统,要输入请假开始时间和结束时间,同时计算出请假天数,如果年假数量不够提示不能提交,如果年假数量够的话,就走审批工作 ...

  5. 请假时长计算和每月工作天数计算

    绪论 请假时长计算和每月工作天数计算其实六月份开发OA系统时就已经写出来了,只是一直没时间去整理,其实最近也很忙,毕竟年底要清一些开发任务.不过感觉自己今年博客写的太少了,所以这些日子基本每天都在加班 ...

  6. java 计算请假天数,去掉节假日

    计算请假天数,去掉节假日的 前端 function countDays() {//外出开始日期var startDate = new Date(DSF.getElementValueByKey(&qu ...

  7. Java计算请假时长(根据规则设置去除节假日、休息日、特殊日期)

    首先选择的日期要判断是不是节假日: 这里是写了工具类获取全年的日期信息. dateUtils工具类 某年第一天可以直接拼接 yyyy-01-01 获取节假日方法: public class DateU ...

  8. 计算请假工时,去除周六周末的时间

    做项目时,写到一个请假的模块,需要计算请假工时,去除周六周末,时间为一天8H,8:00-17:00,中午12:00-13:00 为午休时间 function getLeaveTime(startDat ...

  9. 数据可视化大屏电商数据展示平台开发实录(Echarts柱图曲线图、mysql筛选统计语句、时间计算、大数据量统计)

    数据可视化大屏电商数据展示平台 一.前言 二.项目介绍 三.项目展示 四.项目经验分享 4.1 翻牌器 4.1.1 翻牌器-今日实时交易 4.1.2.翻牌器后端统计SUM函数的使用 4.2 不同时间指 ...

  10. 【SQL开发实战技巧】系列(十七):数据仓库中时间类型操作(初级)确定两个日期之间的工作天数、计算—年中周内各日期出现次数、确定当前记录和下一条记录之间相差的天数

    系列文章目录 [SQL开发实战技巧]系列(一):关于SQL不得不说的那些事 [SQL开发实战技巧]系列(二):简单单表查询 [SQL开发实战技巧]系列(三):SQL排序的那些事 [SQL开发实战技巧] ...

最新文章

  1. java清空字符串_java面向对象,垃圾回收机制
  2. Eclipse-Java代码规范和质量检查插件-SonarLint
  3. 《Linux设备驱动开发详解 A》一一2.3 接口与总线
  4. python遍历字典的四种方法
  5. BZOJ1795 : [Ioi2008]Pyramid Base 金字塔地基
  6. java实用教程——组件及事件处理——布局管理(五种)
  7. Lecture 6 Order Statistics
  8. 可扩展的编程语言——Scala
  9. 写python脚本管理_《写给系统管理员的 Python 脚本编程指南》笔记——第八章 文档和报告...
  10. 电子类公司笔试题精选
  11. JSP 2.2规范 对jsp:useBean的解释
  12. android录屏软件大全,安卓免费录屏软件哪个好用 免费长时间录屏软件推荐
  13. MCMC蒙特卡洛算法
  14. 【SPSS】SPSS之主成分分析及因子分析
  15. 布衣联盟装机常用软件光盘——金鼠报春版
  16. 肯德尔系数怎么分析_肯德尔和谐系数
  17. Shell中如何删除首行和尾行
  18. python数据分析与可视化答案学堂云_智慧树知到_Python数据分析与数据可视化_最新答案...
  19. 驾考科目三考试经验谈
  20. 如何计算机使用ssd硬盘启动,如何设置电脑固态硬盘为第一启动

热门文章

  1. webbug靶场-渗透基础
  2. 日期格式化跨年bug,是否与你不期而遇?
  3. Python+Vue计算机毕业设计酒店管理系统(前台后台)i2agu(源码+程序+LW+部署)
  4. Graph Convolutional Tracking
  5. JAVA爬取淘宝、京东、天猫以及苏宁商品历史价格(二)
  6. GTK、GDK、GLIB三者的关系 - 阿堂的专栏 - 博客频道 - CSDN.NET
  7. 杨歌:金融电路与 Web3 经济模型原理 (转载及导言)
  8. 头像 linux,头像制作大师下载-头像制作大师appv1.2.0-Linux公社
  9. Factory reset会黑屏一段时间进入Provision首页
  10. 龙之谷怎么进去服务器维护,龙之谷端游服务器爆满怎么进