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

先上代码后贴图。

1.测试数据

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

var dateStart = '2018-12-01 04:15',dateEnd = '2018-12-08 12:15';
var MS_HOUR = 1000*60*60;

2.时间差毫秒数

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

function getDiff(start, end)
{var s = Date.parse(start),e = Date.parse(end);//取绝对值return Math.abs(e - s);
}console.log(getDiff(dateStart, dateEnd));
输出:
633600000

3.时间差小时数

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

function getDiffByHour(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天,以此类推

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

function getDiffByDay(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;}return result;
}
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然后除去午休时间,最后得到的小时数来计算天数。

function getLeaveDayInOneDay(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);}return diff.d;
};

5.2 请假时间跨越多个日期

计算第一部分的时长:

function getLeaveDaysInTwoDay(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);
};

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

function getDaysOfPeriod(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必须包含,所以需要+1var 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;}
};

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

主函数如下:

function getLeaveDays(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);}return diff;
};
function getLeaveByHour(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));}return diff;
};

再贴上测试效果吧:

Javascript 计算请假天数相关推荐

  1. 计算请假天数JavaScript方法

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

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

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

  3. 通过开始日期结束日期算请假天数

    在实体中两个Date属性的变量加上注解. 加注解后得到的startDate为YYYY-MM-DD格式 @DateTimeFormat(pattern = SimpleDateUtil.COMMON_D ...

  4. html计算天数,Javascript实现简易天数计算器

    本文实例为大家分享了Javascript实现简易天数计算器的具体代码,供大家参考,具体内容如下 效果图: 功能: 1. 支持选择日期: 2. 自动计算闰年: 3. 支持使用当前日期. 代码: (1)h ...

  5. javaScript 计算两个日期的天数相差~~~

    一:计算两个日期相差的天数 比如:    str1  =  "2002-01-20"    str2  =  "2002-10-11"   怎样用javaScr ...

  6. JavaScript 计算相隔日期之间的天数、小时数、分钟数、秒数

    const shijian =() =>{     let EndTIME:any = new Date('2023-07-28 20:00:00'); // 截止时间     let NowT ...

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

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

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

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

  9. html 表格自动计算,HTML表格中的JavaScript计算

    我是 JavaScript的新手,所以我甚至不知道这是否是尝试这个的正确语言,但我想我会尝试.我已经阅读了其他几篇文章,我找不到真正让我知道如何做到这一点的东西,所以我在这里问.我读过的所有例子都涉及 ...

最新文章

  1. SecureCRT图形界面(通过设置调用Xmanager - Passive程序)
  2. C++ this指针详解(精辟)
  3. 云计算机是一种基于资源,一种基于云平台和云计算的资源管理系统和方法
  4. Python使用request包请求网页乱码解决方法
  5. manually create IBASE 03 in CRM
  6. mysql读写分离-借助中间键mycat
  7. beta分布_浅谈分布之分布(beta分布)贝叶斯分析之1 精选
  8. ecshop源码分析:会话类cls_session
  9. Java程序调用OpenDDS
  10. 2.1.5、会员权限管理系统应用
  11. java转换docx为doc文件_JAVA - 将doc文档转为docx文档
  12. Dell T40服务器系统安装问题
  13. java实现多媒体播放器_JAVA播放器设计
  14. 基于MATLAB中的GUI设计的钢琴界面设计并能发声
  15. FITC标记亲和纯化大鼠抗小鼠IgG(H+L)二抗说明书
  16. 今天,你开发了吗?有成为这1/1000000了吗
  17. 用软碟通制作系统启动盘的诀窍,不掌握永远成不了老司机!
  18. Altium Vault 2.5.9.45043 1CD统一元器件库及复用模块管理
  19. php为什么要有抽象类,通过具体程序来理解PHP里面的抽象类
  20. 电子挂历(万年历)样式

热门文章

  1. 工业交换机智能监控管理方案
  2. 围剿慢SQL,工行MySQL研发管控和治理实践
  3. ‘class QFontMetrics‘ has no member named ‘horizontalAdvance‘
  4. NR 5G 入网流程
  5. Java回炉学习(七)
  6. 行测测评(二)——图形找规律技巧
  7. matlab实时摄像头处理,在MATLAB中调用摄像头实时地显示图像
  8. ps导出内容快捷键 快速导出png
  9. 「GitLab篇」如何用Git平台账号登录建木CI
  10. vue 简单实现上一题下一题问答效果