Самая большая ошибка в том, что вы не написали набор тестов:
- Чтобы проверить пограничный случай, который вы знаете во время разработки
- Чтобы позже легко проверить другой обнаруженный пограничный случай
- Тестируемый код обычно более модульный (см. Ниже фиктивный объект Я должен был создать, чтобы обойти сильную связь вашей функции с jQuery: было бы проще, если бы вызов jQuery былиз
calculateTime
)
Это называется разработка на основе тестирования .
Теперь вот еще несколько ошибок, которые янайдено:
- Ваш формат строки даты не соответствует спецификации .Ваша система понимает ваш формат, но некоторые могут этого не делать.
- В ваших строках даты не указан часовой пояс, поэтому у вас возникнут проблемы с локалью, для которых предусмотрено летнее время.
- Ваша функция даст вам эффективную работуистекшее время, но это может быть не то, что интересует ваших пользователей. В частности, когда используется летнее время: у вас может быть + 1 / -1 час.
Вот набор тестов, который работает отприглашение командной строки Windows (используйте cscript testsuite.js
для его запуска):
// 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');
Вот мой вывод (смещение локального часового пояса (Франция) изменилось на 2010-10-31 и 2011-03-26):
ok
ok
not ok - [Wed Nov 24 23:00:00 UTC+0100 2010] to [Tue Nov 24 22:59:00 UTC+0100 2020]
# Got: 10 Years, 2 Days, 23 Hours, 59 Minutes, 0 Seconds
# Expected: 10 Years, 0 Days, 0 Hours, 0 Minutes, 0 Seconds
not ok - [Sat Mar 26 23:00:00 UTC+0100 2011] to [Sun Mar 27 23:00:00 UTC+0200 2011]
# Got: 0 Years, 0 Days, 23 Hours, 0 Minutes, 0 Seconds
# Expected: 0 Years, 1 Days, 0 Hours, 0 Minutes, 0 Seconds
not ok - [Sat Oct 30 23:00:00 UTC+0200 2010] to [Sun Oct 31 23:00:00 UTC+0100 2010]
# Got: 0 Years, 1 Days, 1 Hours, 0 Minutes, 0 Seconds
# Expected: 0 Years, 1 Days, 0 Hours, 0 Minutes, 0 Seconds
Таким образом, вы должны полностью переписать функцию или лучше, использовать существующую, протестированную реализацию.