Javascript 计算请假天数
计算请假天数,笼统来说就是计算两个日期的差值。对于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 计算请假天数相关推荐
- 计算请假天数JavaScript方法
计算请假天数JavaScript方法 前言 最近,有这么个需求,给用户做个请假审批系统,要输入请假开始时间和结束时间,同时计算出请假天数,如果年假数量不够提示不能提交,如果年假数量够的话,就走审批工作 ...
- java 计算请假天数,去掉节假日
计算请假天数,去掉节假日的 前端 function countDays() {//外出开始日期var startDate = new Date(DSF.getElementValueByKey(&qu ...
- 通过开始日期结束日期算请假天数
在实体中两个Date属性的变量加上注解. 加注解后得到的startDate为YYYY-MM-DD格式 @DateTimeFormat(pattern = SimpleDateUtil.COMMON_D ...
- html计算天数,Javascript实现简易天数计算器
本文实例为大家分享了Javascript实现简易天数计算器的具体代码,供大家参考,具体内容如下 效果图: 功能: 1. 支持选择日期: 2. 自动计算闰年: 3. 支持使用当前日期. 代码: (1)h ...
- javaScript 计算两个日期的天数相差~~~
一:计算两个日期相差的天数 比如: str1 = "2002-01-20" str2 = "2002-10-11" 怎样用javaScr ...
- JavaScript 计算相隔日期之间的天数、小时数、分钟数、秒数
const shijian =() =>{ let EndTIME:any = new Date('2023-07-28 20:00:00'); // 截止时间 let NowT ...
- Java计算请假时长(根据规则设置去除节假日、休息日、特殊日期)
首先选择的日期要判断是不是节假日: 这里是写了工具类获取全年的日期信息. dateUtils工具类 某年第一天可以直接拼接 yyyy-01-01 获取节假日方法: public class DateU ...
- 计算请假工时,去除周六周末的时间
做项目时,写到一个请假的模块,需要计算请假工时,去除周六周末,时间为一天8H,8:00-17:00,中午12:00-13:00 为午休时间 function getLeaveTime(startDat ...
- html 表格自动计算,HTML表格中的JavaScript计算
我是 JavaScript的新手,所以我甚至不知道这是否是尝试这个的正确语言,但我想我会尝试.我已经阅读了其他几篇文章,我找不到真正让我知道如何做到这一点的东西,所以我在这里问.我读过的所有例子都涉及 ...
最新文章
- SecureCRT图形界面(通过设置调用Xmanager - Passive程序)
- C++ this指针详解(精辟)
- 云计算机是一种基于资源,一种基于云平台和云计算的资源管理系统和方法
- Python使用request包请求网页乱码解决方法
- manually create IBASE 03 in CRM
- mysql读写分离-借助中间键mycat
- beta分布_浅谈分布之分布(beta分布)贝叶斯分析之1 精选
- ecshop源码分析:会话类cls_session
- Java程序调用OpenDDS
- 2.1.5、会员权限管理系统应用
- java转换docx为doc文件_JAVA - 将doc文档转为docx文档
- Dell T40服务器系统安装问题
- java实现多媒体播放器_JAVA播放器设计
- 基于MATLAB中的GUI设计的钢琴界面设计并能发声
- FITC标记亲和纯化大鼠抗小鼠IgG(H+L)二抗说明书
- 今天,你开发了吗?有成为这1/1000000了吗
- 用软碟通制作系统启动盘的诀窍,不掌握永远成不了老司机!
- Altium Vault 2.5.9.45043 1CD统一元器件库及复用模块管理
- php为什么要有抽象类,通过具体程序来理解PHP里面的抽象类
- 电子挂历(万年历)样式
热门文章
- 工业交换机智能监控管理方案
- 围剿慢SQL,工行MySQL研发管控和治理实践
- ‘class QFontMetrics‘ has no member named ‘horizontalAdvance‘
- NR 5G 入网流程
- Java回炉学习(七)
- 行测测评(二)——图形找规律技巧
- matlab实时摄像头处理,在MATLAB中调用摄像头实时地显示图像
- ps导出内容快捷键 快速导出png
- 「GitLab篇」如何用Git平台账号登录建木CI
- vue 简单实现上一题下一题问答效果