javascript 在javascript日期计算中排除周末
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/28286293/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
exclude weekends in javascript date calculation
提问by marv
I have two sets of codes that work. Needed help combining them into one.
我有两组有效的代码。需要帮助将它们合二为一。
This code gets me the difference between two dates. works perfectly:
这段代码让我知道两个日期之间的差异。完美运行:
function test(){
var date1 = new Date(txtbox_1.value);
var date2 = new Date(txtbox_2.value);
var diff = (date2 - date1)/1000;
var diff = Math.abs(Math.floor(diff));
var days = Math.floor(diff/(24*60*60));
var leftSec = diff - days * 24*60*60;
var hrs = Math.floor(leftSec/(60*60));
var leftSec = leftSec - hrs * 60*60;
var min = Math.floor(leftSec/(60));
var leftSec = leftSec - min * 60;
txtbox_3.value = days + "." + hrs; }
The code below by @cyberfly appears to have the answer of excluding sat and sun which is what i needed. source. However, its in jquery and the above code is in JS. Therefore, needed help combining as i lacked that knowledge :(
@cyberfly 下面的代码似乎有排除 sat 和 sun 的答案,这正是我需要的。来源。但是,它在 jquery 中,上面的代码在 JS 中。因此,需要帮助结合,因为我缺乏知识:(
<script type="text/javascript">
$("#startdate, #enddate").change(function() {
var d1 = $("#startdate").val();
var d2 = $("#enddate").val();
var minutes = 1000*60;
var hours = minutes*60;
var day = hours*24;
var startdate1 = getDateFromFormat(d1, "d-m-y");
var enddate1 = getDateFromFormat(d2, "d-m-y");
var days = calcBusinessDays(new Date(startdate1),new Date(enddate1));
if(days>0)
{ $("#noofdays").val(days);}
else
{ $("#noofdays").val(0);}
});
</script>
EDITMade an attempt at combining the codes. here is my sample. getting object expected error.
编辑尝试结合代码。这是我的样本。获取对象预期错误。
function test(){
var date1 = new Date(startdate.value);
var date2 = new Date(enddate.value);
var diff = (date2 - date1)/1000;
var diff = Math.abs(Math.floor(diff));
var days = Math.floor(diff/(24*60*60));
var leftSec = diff - days * 24*60*60;
var hrs = Math.floor(leftSec/(60*60));
var leftSec = leftSec - hrs * 60*60;
var min = Math.floor(leftSec/(60));
var leftSec = leftSec - min * 60;
var startdate1 = getDateFromFormat(startdate, "dd/mm/yyyy hh:mm");
var enddate1 = getDateFromFormat(enddate, "dd/mm/yyyy hh:mm");
days = calcBusinessDays(new Date(startdate1),new Date(enddate1));
noofdays.value = days + "." + hrs; }
start: <input type="text" id="startdate" name="startdate" value="02/03/2015 00:00">
end: <input type="text" id="enddate" name="enddate" value="02/03/2015 00:01">
<input type="text" id="noofdays" name="noofdays" value="">
回答by RobG
When determining the number of days between two dates, there are lots of decisions to be made about what is a day. For example, the period 1 Feb to 2 Feb is generally one day, so 1 Feb to 1 Feb is zero days.
在确定两个日期之间的天数时,需要做出很多关于什么是一天的决定。例如,2月1日至2月2日期间一般为1天,因此2月1日至2月1日为0天。
When adding the complexity of counting only business days, things get a lot tougher. E.g. Monday 2 Feb 2015 to Friday 6 February is 4 elapsed days (Monday to Tuesday is 1, Monday to Wednesday is 2, etc.), however the expression "Monday to Friday" is generally viewed as 5 business days and the duration Mon 2 Feb to Sat 7 Feb should also be 4 business days, but Sunday to Saturday should be 5.
当增加仅计算工作日的复杂性时,事情会变得更加困难。例如,从 2015 年 2 月 2 日星期一到 2 月 6 日星期五是 4 天(星期一到星期二是 1,星期一到星期三是 2,等等),但是表达“星期一到星期五”通常被视为 5 个工作日,持续时间为星期一 2 2 月至 2 月 7 日周六也应为 4 个工作日,但周日至周六应为 5 个工作日。
So here's my algorithm:
所以这是我的算法:
- Get the total number of whole days between the two dates
- Divide by 7 to get the number of whole weeks
- Multiply the number of weeks by two to get the number of weekend days
- Subtract the number of weekend days from the whole to get business days
- If the number of total days is not an even number of weeks, add the numbe of weeks * 7 to the start date to get a temp date
- While the temp date is less than the end date:
- if the temp date is not a Saturday or Sunday, add one the business days
- add one to the temp date
- That's it.
- 获取两个日期之间的总天数
- 除以 7 得到整周数
- 将周数乘以 2 得到周末天数
- 从总数中减去周末天数得到工作日
- 如果总天数不是偶数周数,则将周数 * 7 添加到开始日期以获得临时日期
- 虽然临时日期小于结束日期:
- 如果临时日期不是星期六或星期日,请添加一个工作日
- 添加一个到临时日期
- 而已。
The stepping part at the end can probably be replaced by some other algorithm, but it will never loop for more than 6 days so it's a simple and reasonably efficient solution to the issue of uneven weeks.
最后的步进部分可能会被其他一些算法取代,但它永远不会循环超过 6 天,因此它是解决不均匀周问题的简单且合理有效的解决方案。
Some consequences of the above:
以上的一些后果:
- Monday to Friday is 4 business days
- Any day to the same day in a different week is an even number of weeks and therefore an even mutiple of 5, e.g. Monday 2 Feb to Monday 9 Feb and Sunday 1 Feb to Sunday 8 Feb are 5 business days
- Friday 6 Feb to Sunday 7 Feb is zero business days
- Friday 6 Feb to Monday 9 Feb is one business day
- Sunday 8 Feb to: Sunday 15 Feb, Sat 14 Feb and Fri 13 Feb are all 5 business days
- 周一至周五为 4 个工作日
- 不同周中同一天的任何一天都是偶数周,因此是 5 的偶数倍数,例如 2 月 2 日星期一至 2 月 9 日星期一和 2 月 1 日星期日至 2 月 8 日星期日是 5 个工作日
- 2 月 6 日星期五至 2 月 7 日星期日为零工作日
- 2月6日星期五至2月9日星期一是一个工作日
- 2 月 8 日星期日至:2 月 15 日星期日、2 月 14 日星期六和 2 月 13 日星期五均为 5 个工作日
Here's the code:
这是代码:
// Expects start date to be before end date
// start and end are Date objects
function dateDifference(start, end) {
// Copy date objects so don't modify originals
var s = new Date(+start);
var e = new Date(+end);
// Set time to midday to avoid dalight saving and browser quirks
s.setHours(12,0,0,0);
e.setHours(12,0,0,0);
// Get the difference in whole days
var totalDays = Math.round((e - s) / 8.64e7);
// Get the difference in whole weeks
var wholeWeeks = totalDays / 7 | 0;
// Estimate business days as number of whole weeks * 5
var days = wholeWeeks * 5;
// If not even number of weeks, calc remaining weekend days
if (totalDays % 7) {
s.setDate(s.getDate() + wholeWeeks * 7);
while (s < e) {
s.setDate(s.getDate() + 1);
// If day isn't a Sunday or Saturday, add to business days
if (s.getDay() != 0 && s.getDay() != 6) {
++days;
}
}
}
return days;
}
Dunno how it compares to jfriend00's answer or the code you referenced, if you want the period to be inclusive, just add one if the start or end date are a business day.
不知道它与 jfriend00 的答案或您引用的代码相比如何,如果您希望该期间包含在内,如果开始或结束日期是工作日,只需添加一个。
回答by jfriend00
Here's a simple function to calculate the number of business days between two date objects. As designed, it does not count the start day, but does count the end day so if you give it a date on a Tuesday of one week and a Tuesday of the next week, it will return 5 business days. This does not account for holidays, but does work properly across daylight savings changes.
这是一个计算两个日期对象之间的工作日数的简单函数。按照设计,它不计算开始日,但计算结束日,因此如果您在一周的周二和下周的周二为其指定日期,它将返回 5 个工作日。这不考虑假期,但在夏令时变化中可以正常工作。
function calcBusinessDays(start, end) {
// This makes no effort to account for holidays
// Counts end day, does not count start day
// make copies we can normalize without changing passed in objects
var start = new Date(start);
var end = new Date(end);
// initial total
var totalBusinessDays = 0;
// normalize both start and end to beginning of the day
start.setHours(0,0,0,0);
end.setHours(0,0,0,0);
var current = new Date(start);
current.setDate(current.getDate() + 1);
var day;
// loop through each day, checking
while (current <= end) {
day = current.getDay();
if (day >= 1 && day <= 5) {
++totalBusinessDays;
}
current.setDate(current.getDate() + 1);
}
return totalBusinessDays;
}
And, the jQuery + jQueryUI code for a demo:
并且,用于演示的 jQuery + jQueryUI 代码:
// make both input fields into date pickers
$("#startDate, #endDate").datepicker();
// process click to calculate the difference between the two days
$("#calc").click(function(e) {
var diff = calcBusinessDays(
$("#startDate").datepicker("getDate"),
$("#endDate").datepicker("getDate")
);
$("#diff").html(diff);
});
And, here's a simple demo built with the date picker in jQueryUI: http://jsfiddle.net/jfriend00/z1txs10d/
而且,这是一个使用 jQueryUI 中的日期选择器构建的简单演示:http: //jsfiddle.net/jfriend00/z1txs10d/
回答by Pranav
@RobG has given an excellent algorithm to separate business days from weekends. I think the only problem is if the starting days is a weekend, Saturday or Sunday, then the no of working days/weekends will one less.
@RobG 提供了一种出色的算法来将工作日与周末分开。我认为唯一的问题是如果开始日期是周末、周六或周日,那么工作日/周末的数量会减少一个。
Corrected code is below.
更正后的代码如下。
function dateDifference(start, end) {
// Copy date objects so don't modify originals
var s = new Date(start);
var e = new Date(end);
var addOneMoreDay = 0;
if( s.getDay() == 0 || s.getDay() == 6 ) {
addOneMoreDay = 1;
}
// Set time to midday to avoid dalight saving and browser quirks
s.setHours(12,0,0,0);
e.setHours(12,0,0,0);
// Get the difference in whole days
var totalDays = Math.round((e - s) / 8.64e7);
// Get the difference in whole weeks
var wholeWeeks = totalDays / 7 | 0;
// Estimate business days as number of whole weeks * 5
var days = wholeWeeks * 5;
// If not even number of weeks, calc remaining weekend days
if (totalDays % 7) {
s.setDate(s.getDate() + wholeWeeks * 7);
while (s < e) {
s.setDate(s.getDate() + 1);
// If day isn't a Sunday or Saturday, add to business days
if (s.getDay() != 0 && s.getDay() != 6) {
++days;
}
//s.setDate(s.getDate() + 1);
}
}
var weekEndDays = totalDays - days + addOneMoreDay;
return weekEndDays;
}
JSFiddle link is https://jsfiddle.net/ykxj4k09/2/
JSFiddle 链接是https://jsfiddle.net/ykxj4k09/2/
回答by Jagadish Jorige
First Get the Number of Days in a month
首先获取一个月的天数
totalDays(month, year) {
return new Date(year, month, 0).getDate();
}
Then Get No Of Working Days In A Month By removing Saturday and Sunday
然后通过删除星期六和星期日来获得一个月内的工作日数
totalWorkdays() {
var d = new Date(); // to know present date
var m = d.getMonth() + 1; // to know present month
var y = d.getFullYear(); // to knoow present year
var td = this.totalDays(m, y);// to get no of days in a month
for (var i = 1; i <= td; i++) {
var s = new Date(y, m - 1, i);
if (s.getDay() != 0 && s.getDay() != 6) {
this.workDays.push(s.getDate());// working days
}else {
this.totalWeekDays.push(s.getDate());//week days
}
}
this.totalWorkingDays = this.workDays.length;
}