我有一个在时代中占用时间戳的函数(如1517073001
)并以简单的格式返回自那时以来经过的时间,例如" 2小时前" (不会像#34; 2小时,31分15秒前那样进一步啰嗦")。
该函数按预期工作,但JSHint抱怨使用太多语句(30)并且其圈复杂度太高(12)。我想知道什么是改善这两个方面的方法。
这是功能:
function msToTime(epoch) {
var previous = new Date(epoch * 1000);
var current = Math.floor(new Date().getTime());
var ms = current - previous;
var years = parseInt((ms / (1000 * 60 * 60 * 24 * 30 * 12)).toFixed(20), 10);
var months = parseInt((ms / (1000 * 60 * 60 * 24 * 30) % 12).toFixed(20), 10);
var days = parseInt((ms / (1000 * 60 * 60 * 24) % 30).toFixed(20), 10);
var hours = parseInt((ms / (1000 * 60 * 60) % 24).toFixed(20), 10);
var minutes = parseInt(ms / (1000 * 60) % 60, 10);
var seconds = parseInt(ms / 1000 % 60, 10);
var formatted = '';
if (years > 0) {
if (years > 1) {
formatted = years + ' years ago';
} else {
formatted = years + ' year ago';
}
} else if (months > 0) {
if (months > 1) {
formatted = months + ' months ago';
} else {
formatted = months + ' month ago';
}
} else if (days > 0) {
if (days > 1) {
formatted = days + ' days ago';
} else {
formatted = days + ' day ago';
}
} else if (hours > 0) {
if (hours > 1) {
formatted = hours + ' hours ago';
} else {
formatted = hours + ' hour ago';
}
} else if (minutes > 0) {
if (minutes > 1) {
formatted = minutes + ' minutes ago';
} else {
formatted = minutes + ' minute ago';
}
} else {
if (seconds > 1) {
formatted = seconds + ' seconds ago';
} else {
formatted = seconds + ' second ago';
}
}
return formatted;
}
var div = document.getElementById('time');
div.innerHTML = msToTime(1517073001);

<div id="time"></div>
&#13;
提前谢谢你。 :)
答案 0 :(得分:2)
针对div和模块操作优化的另一个版本
function msToTime(epoch) {
var value = (Math.floor(new Date().getTime()) - new Date(epoch * 1000)) / 1000;
var time_factors = [['second', 60], ['minute', 60], ['hour', 24], ['day', 30], ['month', 12], ['year', NaN]];
for (factor of time_factors) {
if (value < factor[1] || isNaN(factor[1])) {
var t = Math.floor(value);
return t + ' ' + (t > 1 ? factor[0] + 's' : factor[0]) + ' ago';
}
value /= factor[1];
}
}
答案 1 :(得分:1)
将if...else if...else if...
替换为switch (true)
并将单数或复数的构建放入函数中:
function msToTime(epoch) {
let previous = new Date(epoch * 1000);
let current = Math.floor(new Date().getTime());
let ms = current - previous;
let years = parseInt((ms / (1000 * 60 * 60 * 24 * 30 * 12)).toFixed(20), 10);
let months = parseInt((ms / (1000 * 60 * 60 * 24 * 30) % 12).toFixed(20), 10);
let days = parseInt((ms / (1000 * 60 * 60 * 24) % 30).toFixed(20), 10);
let hours = parseInt((ms / (1000 * 60 * 60) % 24).toFixed(20), 10);
let minutes = parseInt(ms / (1000 * 60) % 60, 10);
let seconds = parseInt(ms / 1000 % 60, 10);
let formatted = '';
function timeAgo(count, word) {
return `${count} ${(count === 1 ? word : word + 's')} ago`
}
switch (true) {
case years > 0:
formatted = timeAgo(years, 'year')
break
case months > 0:
formatted = timeAgo(months, 'month')
break
case days > 0:
formatted = timeAgo(days, 'day')
break
case hours > 0:
formatted = timeAgo(hours, 'hour')
break
case minutes > 0:
formatted = timeAgo(minutes, 'minute')
break
default:
formatted = timeAgo(seconds, 'second')
}
return formatted;
}
time.innerHTML = msToTime(1517073001);
&#13;
<div id="time"></div>
&#13;
答案 2 :(得分:1)
将日期定义为数组并迭代它会将Cyclomatic复杂度数字减少到4(!),只有12个语句。
function msToTime(epoch) {
var previous = new Date(epoch * 1000);
var current = Math.floor(new Date().getTime());
var ms = current - previous;
var formatted = '';
var completeDate = [
['year', parseInt((ms / (1000 * 60 * 60 * 24 * 30 * 12)).toFixed(20), 10)],
['month', parseInt((ms / (1000 * 60 * 60 * 24 * 30) % 12).toFixed(20), 10)],
['day', parseInt((ms / (1000 * 60 * 60 * 24) % 30).toFixed(20), 10)],
['hour', parseInt((ms / (1000 * 60 * 60) % 24).toFixed(20), 10)],
['minute', parseInt(ms / (1000 * 60) % 60, 10)],
['second', parseInt(ms / 1000 % 60, 10)]
];
for (var i = 0; i < completeDate.length; i++) {
var amount = completeDate[i][1];
if (amount > 0) {
var unit = completeDate[i][0];
formatted = amount + ' ' + (amount > 1 ? unit + 's' : unit) + ' ago';
break;
}
}
return formatted;
}
var div = document.getElementById('time');
div.innerHTML = msToTime(1517073001);
<div id="time"></div>
感谢@connexo提供重要建议!
答案 3 :(得分:-1)
function msToTime (epoch) {
var previous = new Date(epoch * 1000);
var current = Math.floor(new Date().getTime());
var ms = current - previous;
var years = parseInt((ms / (1000 * 60 * 60 * 24 * 30 * 12)).toFixed(20), 10);
var months = parseInt((ms / (1000 * 60 * 60 * 24 * 30) % 12).toFixed(20), 10);
var days = parseInt((ms / (1000 * 60 * 60 * 24) % 30).toFixed(20), 10);
var hours = parseInt((ms / (1000 * 60 * 60) % 24).toFixed(20), 10);
var minutes = parseInt(ms / (1000 * 60) % 60, 10);
var seconds = parseInt(ms / 1000 % 60, 10);
var formatted = '';
if (years > 0) {
formatted = years > 1 ? years + ' years ago' : years + ' year ago';
} else if (months > 0) {
formatted = months > 1 ? ' months ago' : ' month ago';
} else if (days > 0) {
formatted = days > 1 ? ' days ago' : ' day ago';
} else if (hours > 0) {
formatted = hours > 1 ? ' hours ago' : ' hour ago';
} else if (minutes > 0) {
formatted = minutes > 1 ? ' minutes ago' : ' minute ago';
} else {
formatted = seconds > 1 ? ' seconds ago' : ' second ago';
}
return formatted;
}
var div = document.getElementById('time');
div.innerHTML = msToTime(1417073002);
我使用JS三元运算符来缩短你的代码。希望它有所帮助。