问题是如何将JavaScript Date格式化为一个字符串,声明时间经过,类似于您在Stack Overflow上看到的时间显示方式。
e.g.
1分钟前 1小时前 1天前 1个月前 一年前
问题是如何将JavaScript Date格式化为一个字符串,声明时间经过,类似于您在Stack Overflow上看到的时间显示方式。
e.g.
1分钟前 1小时前 1天前 1个月前 一年前
当前回答
我修改了Sky Sanders的版本。Math.floor(…)操作在if块中计算
var timeSince = function(date) {
var seconds = Math.floor((new Date() - date) / 1000);
var months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
if (seconds < 5){
return "just now";
}else if (seconds < 60){
return seconds + " seconds ago";
}
else if (seconds < 3600) {
minutes = Math.floor(seconds/60)
if(minutes > 1)
return minutes + " minutes ago";
else
return "1 minute ago";
}
else if (seconds < 86400) {
hours = Math.floor(seconds/3600)
if(hours > 1)
return hours + " hours ago";
else
return "1 hour ago";
}
//2 days and no more
else if (seconds < 172800) {
days = Math.floor(seconds/86400)
if(days > 1)
return days + " days ago";
else
return "1 day ago";
}
else{
//return new Date(time).toLocaleDateString();
return date.getDate().toString() + " " + months[date.getMonth()] + ", " + date.getFullYear();
}
}
其他回答
function timeago(date) {
var seconds = Math.floor((new Date() - date) / 1000);
if(Math.round(seconds/(60*60*24*365.25)) >= 2) return Math.round(seconds/(60*60*24*365.25)) + " years ago";
else if(Math.round(seconds/(60*60*24*365.25)) >= 1) return "1 year ago";
else if(Math.round(seconds/(60*60*24*30.4)) >= 2) return Math.round(seconds/(60*60*24*30.4)) + " months ago";
else if(Math.round(seconds/(60*60*24*30.4)) >= 1) return "1 month ago";
else if(Math.round(seconds/(60*60*24*7)) >= 2) return Math.round(seconds/(60*60*24*7)) + " weeks ago";
else if(Math.round(seconds/(60*60*24*7)) >= 1) return "1 week ago";
else if(Math.round(seconds/(60*60*24)) >= 2) return Math.round(seconds/(60*60*24)) + " days ago";
else if(Math.round(seconds/(60*60*24)) >= 1) return "1 day ago";
else if(Math.round(seconds/(60*60)) >= 2) return Math.round(seconds/(60*60)) + " hours ago";
else if(Math.round(seconds/(60*60)) >= 1) return "1 hour ago";
else if(Math.round(seconds/60) >= 2) return Math.round(seconds/60) + " minutes ago";
else if(Math.round(seconds/60) >= 1) return "1 minute ago";
else if(seconds >= 2)return seconds + " seconds ago";
else return seconds + "1 second ago";
}
我一直在寻找这个问题的答案,并且几乎实现了其中一个解决方案,但一位同事提醒我检查react-intl库,因为我们已经在使用它了。
所以在解决方案中…在使用react-intl库的情况下,它们有一个<FormattedRelative>组件。
https://github.com/yahoo/react-intl/wiki/Components#formattedrelative
由@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编辑建议。(谢谢!)
function timeSince(date) { var seconds = Math.floor((new Date() - date) / 1000); var interval = seconds / 31536000; if (interval > 1) { return Math.floor(interval) + " years"; } interval = seconds / 2592000; if (interval > 1) { return Math.floor(interval) + " months"; } interval = seconds / 86400; if (interval > 1) { return Math.floor(interval) + " days"; } interval = seconds / 3600; if (interval > 1) { return Math.floor(interval) + " hours"; } interval = seconds / 60; if (interval > 1) { return Math.floor(interval) + " minutes"; } return Math.floor(seconds) + " seconds"; } var aDay = 24*60*60*1000; console.log(timeSince(new Date(Date.now()-aDay))); console.log(timeSince(new Date(Date.now()-aDay*2)));
回复@Stas Parshin的答案,这是最好的答案,代码更少,但它在与typescript一起使用时有bug, Intl的.format函数需要2个输入
number, Units - i.e of type 'RelativeTimeFormatUnit' so if you pass a object key typescript will through error saying unit must be of type RelativeTimeFormatUnit and not of type string, so the work-around for this is to use the type to make another list of same type and rest you can have look at code... Happy coding. 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 }; type RelativeTimeFormatUnit = | "year" | "years" | "quarter" | "quarters" | "month" | "months" | "week" | "weeks" | "day" | "days" | "hour" | "hours" | "minute" | "minutes" | "second" | "seconds" ; const units: RelativeTimeFormatUnit[] = ["years", "months", "weeks", "days", "hours", "minutes", "seconds"]; // order matters here. const secondsElapsed = (date.getTime() - Date.now()) / 1000; for (let key in ranges) { let i = 0; if (ranges[key] < Math.abs(secondsElapsed)) { const delta = secondsElapsed / ranges[key]; return formatter.format(Math.round(delta), units[i++]); } } }