问题是如何将JavaScript Date格式化为一个字符串,声明时间经过,类似于您在Stack Overflow上看到的时间显示方式。
e.g.
1分钟前 1小时前 1天前 1个月前 一年前
问题是如何将JavaScript Date格式化为一个字符串,声明时间经过,类似于您在Stack Overflow上看到的时间显示方式。
e.g.
1分钟前 1小时前 1天前 1个月前 一年前
当前回答
由@user1012181提供的ES6版本代码:
const epochs = [
['year', 31536000],
['month', 2592000],
['day', 86400],
['hour', 3600],
['minute', 60],
['second', 1]
];
const getDuration = (timeAgoInSeconds) => {
for (let [name, seconds] of epochs) {
const interval = Math.floor(timeAgoInSeconds / seconds);
if (interval >= 1) {
return {
interval: interval,
epoch: name
};
}
}
};
const timeAgo = (date) => {
const timeAgoInSeconds = Math.floor((new Date() - new Date(date)) / 1000);
const {interval, epoch} = getDuration(timeAgoInSeconds);
const suffix = interval === 1 ? '' : 's';
return `${interval} ${epoch}${suffix} ago`;
};
由@ibe-vanmeenen编辑建议。(谢谢!)
其他回答
可读性强且跨浏览器兼容的代码:
@Travis给出的
var DURATION_IN_SECONDS = { epochs: ['year', 'month', 'day', 'hour', 'minute'], year: 31536000, month: 2592000, day: 86400, hour: 3600, minute: 60 }; function getDuration(seconds) { var epoch, interval; for (var i = 0; i < DURATION_IN_SECONDS.epochs.length; i++) { epoch = DURATION_IN_SECONDS.epochs[i]; interval = Math.floor(seconds / DURATION_IN_SECONDS[epoch]); if (interval >= 1) { return { interval: interval, epoch: epoch }; } } }; function timeSince(date) { var seconds = Math.floor((new Date() - new Date(date)) / 1000); var duration = getDuration(seconds); var suffix = (duration.interval > 1 || duration.interval === 0) ? 's' : ''; return duration.interval + ' ' + duration.epoch + suffix; }; alert(timeSince('2015-09-17T18:53:23'));
您可能需要查看humanized_time_span: https://github.com/layam/js_humanized_time_span
它与框架无关,并且完全可定制。
只需下载/包含脚本,然后你可以这样做:
humanized_time_span("2011-05-11 12:00:00")
=> '3 hours ago'
humanized_time_span("2011-05-11 12:00:00", "2011-05-11 16:00:00)
=> '4 hours ago'
甚至是这样:
var custom_date_formats = {
past: [
{ ceiling: 60, text: "less than a minute ago" },
{ ceiling: 86400, text: "$hours hours, $minutes minutes and $seconds seconds ago" },
{ ceiling: null, text: "$years years ago" }
],
future: [
{ ceiling: 60, text: "in less than a minute" },
{ ceiling: 86400, text: "in $hours hours, $minutes minutes and $seconds seconds time" },
{ ceiling: null, text: "in $years years" }
]
}
humanized_time_span("2010/09/10 10:00:00", "2010/09/10 10:00:05", custom_date_formats)
=> "less than a minute ago"
更多信息请阅读文档。
这应该正确地处理任何有效的时间戳,包括Date.now()、单数单位和未来日期。我漏掉了月份,但是这些月份应该很容易加进去。我尽量保持它的可读性。
function getTimeInterval(date) { let seconds = Math.floor((Date.now() - date) / 1000); let unit = "second"; let direction = "ago"; if (seconds < 0) { seconds = -seconds; direction = "from now"; } let value = seconds; if (seconds >= 31536000) { value = Math.floor(seconds / 31536000); unit = "year"; } else if (seconds >= 86400) { value = Math.floor(seconds / 86400); unit = "day"; } else if (seconds >= 3600) { value = Math.floor(seconds / 3600); unit = "hour"; } else if (seconds >= 60) { value = Math.floor(seconds / 60); unit = "minute"; } if (value != 1) unit = unit + "s"; return value + " " + unit + " " + direction; } console.log(getTimeInterval(Date.now())); // 0 seconds ago console.log(getTimeInterval(Date.now() + 1000)); // 1 second from now console.log(getTimeInterval(Date.now() - 1000)); // 1 second ago console.log(getTimeInterval(Date.now() + 60000)); // 1 minute from now console.log(getTimeInterval(Date.now() - 120000)); // 2 minutes ago console.log(getTimeInterval(Date.now() + 120000)); // 2 minutes from now console.log(getTimeInterval(Date.now() + 3600000)); // 1 hour from now console.log(getTimeInterval(Date.now() + 360000000000)); // 11 years from now console.log(getTimeInterval(0)); // 49 years ago
const createdAt = moment(created_at).fromNow()
量身定制的解决方案
const duration = moment.duration(moment().diff(moment(created_at)))
const createdAt = duration.as('week') >= 1
? `${Math.floor(duration.as('week'))} week(s)`
: duration.as('day') >= 1
? `${Math.floor(duration.as('day'))} day(s)`
: duration.as('hour') >= 1
? `${Math.floor(duration.as('hour'))} hour(s)`
: `${Math.floor(duration.as('minute'))} minute(s)`
这是对国际的另一种看法。RelativeTimeFormat
支持过去日期和将来日期 同时接受字符串和日期 易于添加自定义范围(编辑范围) 可以很容易地翻译为Intl.RelativeTimeFormat('ua')
console.log(timeAgo('2021-08-09T15:29:01+0000')); function timeAgo(input) { const date = (input instanceof Date) ? input : new Date(input); const formatter = new Intl.RelativeTimeFormat('en'); const ranges = { years: 3600 * 24 * 365, months: 3600 * 24 * 30, weeks: 3600 * 24 * 7, days: 3600 * 24, hours: 3600, minutes: 60, seconds: 1 }; const secondsElapsed = (date.getTime() - Date.now()) / 1000; for (let key in ranges) { if (ranges[key] < Math.abs(secondsElapsed)) { const delta = secondsElapsed / ranges[key]; return formatter.format(Math.round(delta), key); } } }
https://jsfiddle.net/tv9701uf