下午,
我正在使用JS计算两个日期之间的差异。我试图将结果精确到一秒钟。我一直很好,但注意到了一个问题。下面显示的前两个日期显示了5年的差异,但是一旦我在未来的日期再添加一年,它会显示5年,1天。额外的一天从哪里来?当未来日期到达2020年时,它会在结果中再添加一天,这是一种反复出现的模式。有人可以开导我吗?我还没有涉及任何闰年计算,我已将我的代码放在下面:
$(document).ready(function(){
var todaysDate = new Date('2010/11/24 23:00:00');
var futureDate = new Date('2020/11/24 22:59:00');
calculateTime(todaysDate,futureDate);
});
function calculateTime(todaysDate,futureDate){
var difference = futureDate.getTime() - todaysDate.getTime();
var years = Math.floor(difference/1000/60/60/24/365);
difference -= years*1000*60*60*24*365;
var days = Math.floor(difference/1000/60/60/24);
difference -= days*1000*60*60*24;
var hours = Math.floor(difference/1000/60/60);
difference -= hours*1000*60*60;
var minutes = Math.floor(difference/1000/60);
difference -= minutes*60*1000;
var seconds = Math.floor(difference/1000);
var result = years + ' Years, ';
result += days + ' Days, ';
result += hours + ' Hours, ';
result += minutes + ' Minutes, ';
result += seconds + ' Seconds';
$('#time').html(result)
}
答案 0 :(得分:4)
是的,2020年是闰年,所以如果您的初步测试是2010-2019,那么您尝试2010-2020,由于闰年还有一天。即使您没有明确处理闰年,Javascript日期对象也是闰年,因此差异将包括额外的一天的秒数。
尝试区别对待
1) 2010/11/24 -> 2020/02/28
2) 2010/11/24 -> 2020/03/01
你最终应该有86,400,000的差异。
答案 1 :(得分:0)
是的,问题出在闰年。你的行
var years = Math.floor(difference/1000/60/60/24/365);
不计算两个日期之间的年数差异,而是计算它们之间的365天期间的数量
答案 2 :(得分:0)
最大的错误是没有编写测试套件:
这称为 test-driven development 。
现在我发现了其他一些错误:
这是一个可以在Windows命令行提示符下运行的测试套件(使用calculateTime
来运行它):
cscript testsuite.js
以下是我的输出(当地时区(法国)偏移在2010-10-31和2011-03-26更改):
// jQuery mock object for calculateTime testing
// $('#time').html(result) => result is stored in $.result
var $ = (function() {
var $, $$ = {
html: function(result) {
$.result = result
}
}
return $ = function(ignore) {
return $$
}
})();
// Henryz's unmodified function
function calculateTime(todaysDate,futureDate) {
var difference = futureDate.getTime() - todaysDate.getTime();
var years = Math.floor(difference/1000/60/60/24/365);
difference -= years*1000*60*60*24*365;
var days = Math.floor(difference/1000/60/60/24);
difference -= days*1000*60*60*24;
var hours = Math.floor(difference/1000/60/60);
difference -= hours*1000*60*60;
var minutes = Math.floor(difference/1000/60);
difference -= minutes*60*1000;
var seconds = Math.floor(difference/1000);
var result = years + ' Years, ';
result += days + ' Days, ';
result += hours + ' Hours, ';
result += minutes + ' Minutes, ';
result += seconds + ' Seconds';
return $('#time').html(result)
}
function test(a, b, expected) {
var toString = Object.prototype.toString;
if (toString.apply(a) != '[object Date]') a = new Date(a);
if (toString.apply(b) != '[object Date]') b = new Date(b);
calculateTime(a, b);
var got = $.result;
WScript.Echo(
got === expected
? "ok"
: "not ok - ["+a.toString()+"] to ["+b.toString()+"]\r\n# Got: "+got+"\r\n# Expected: "+expected
);
}
test('2010/11/24 23:00:00', '2011/11/24 23:00:00', '1 Years, 0 Days, 0 Hours, 0 Minutes, 0 Seconds');
test('Nov 24, 2010 23:00:00', 'Nov 24, 2011 23:00:00', '1 Years, 0 Days, 0 Hours, 0 Minutes, 0 Seconds');
test('2010/11/24 23:00:00', '2020/11/24 22:59:00', '10 Years, 0 Days, 0 Hours, 0 Minutes, 0 Seconds');
test('2011/03/26 23:00:00', '2011/03/27 23:00:00', '0 Years, 1 Days, 0 Hours, 0 Minutes, 0 Seconds');
test('2010/10/30 23:00:00', '2010/10/31 23:00:00', '0 Years, 1 Days, 0 Hours, 0 Minutes, 0 Seconds');
所以你应该完全重写函数或者更好,使用现有的,经过测试的实现。