所以,我有两个日期,来自用户界面:
var start = new Date(self.Start()), end = new Date(self.End());
我们需要弄清楚该范围之间的天数,这很容易:
var days = Math.max(0, Math.floor((end - start) / ticksInDay) || 0);
我们使用此数字来计算某种总工作估算值。但是,现在需要这项工作的权力估计不再包括周末。我的第一次尝试是这样的:
var days = Math.max(0, Math.floor((5 / 7) * (end - start) / ticksInDay) || 0);
基本上,如果范围有7天,我们将其乘以(5 / 7)
以获得5个实际天数。 14会给我们10个实际日子。但是,这有一些缺陷。
(5/7)*1 = 0.714285714285714
(5/7)*2 = 1.42857142857143
(5/7)*3 = 2.14285714285714
(5/7)*4 = 2.85714285714286
(5/7)*5 = 3.57142857142857
(5/7)*6 = 4.28571428571429
(5/7)*7 = 5
(5/7)*8 = 5.71428571428571
(5/7)*9 = 6.42857142857143
(5/7)*10 = 7.14285714285714
(5/7)*11 = 7.85714285714286
(5/7)*12 = 8.57142857142857
(5/7)*13 = 9.28571428571429
(5/7)*14 = 10
舍入(无论哪种方式)在这里都不起作用,因为3或4天,或10或11天的范围将是错误的。我尝试过的任何其他东西都是丑陋的字符串或如果...... thens 或奇怪的条件陈述。
我能想到的唯一方法是100%准确将循环范围,类似于this answer推荐的方式。但是,只要UI模型发生更改,此代码就必须运行,并且需要计算具有潜在大日期范围的潜在大量行的工作估计值。我担心O(n)
解决方案会太慢。
日期范围是否有良好的公式可以排除每7天中的2天?
答案 0 :(得分:6)
// Count days from d0 to d1 inclusive, excluding weekends
function countWeekDays( d0, d1 )
{
var ndays = 1 + Math.round((d1.getTime()-d0.getTime())/(24*3600*1000));
var nsaturdays = Math.floor((ndays + d0.getDay()) / 7);
return ndays - 2*nsaturdays - (d0.getDay()==0) + (d1.getDay()==6);
}
2014年1月的例子:
January 2014
Su Mo Tu We Th Fr Sa
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
countWeekDays(new Date(2014,0,1),new Date(2014,0,1)) // 1
countWeekDays(new Date(2014,0,1),new Date(2014,0,2)) // 2
countWeekDays(new Date(2014,0,1),new Date(2014,0,3)) // 3
countWeekDays(new Date(2014,0,1),new Date(2014,0,4)) // 3
countWeekDays(new Date(2014,0,1),new Date(2014,0,5)) // 3
countWeekDays(new Date(2014,0,1),new Date(2014,0,6)) // 4
N.B。 Date
输入应该在一天的大致同一时间。如果您仅根据上面的示例创建基于年,月和日的Date
个对象,那么您应该没问题。作为一个反例,1月1日上午12点01分到1月2日晚上11:59仅跨越2天,但如果你使用这些时间,上述功能将计为3。