问题是如何将JavaScript Date格式化为一个字符串,声明时间经过,类似于您在Stack Overflow上看到的时间显示方式。
e.g.
1分钟前 1小时前 1天前 1个月前 一年前
问题是如何将JavaScript Date格式化为一个字符串,声明时间经过,类似于您在Stack Overflow上看到的时间显示方式。
e.g.
1分钟前 1小时前 1天前 1个月前 一年前
当前回答
将上面的函数更改为
function timeSince(date) {
var seconds = Math.floor(((new Date().getTime()/1000) - date)),
interval = Math.floor(seconds / 31536000);
if (interval > 1) return interval + "y";
interval = Math.floor(seconds / 2592000);
if (interval > 1) return interval + "m";
interval = Math.floor(seconds / 86400);
if (interval >= 1) return interval + "d";
interval = Math.floor(seconds / 3600);
if (interval >= 1) return interval + "h";
interval = Math.floor(seconds / 60);
if (interval > 1) return interval + "m ";
return Math.floor(seconds) + "s";
}
否则它会显示“75分钟”(介于1到2小时之间)。它现在还假定输入日期是Unix时间戳。
其他回答
在这种情况下可能有点过头了,但如果有机会,moment.js真的很棒!
js是一个javascript datetime库,在这种情况下使用它,你需要做:
moment(yourdate).fromNow()
http://momentjs.com/docs/#/displaying/fromnow/
2018附录:Luxon是一个新的现代图书馆,可能值得一看!
2022年附录:Day.js是一个较新的库,比Luxon轻80%左右,具有类似的功能。
我一直在寻找这个问题的答案,并且几乎实现了其中一个解决方案,但一位同事提醒我检查react-intl库,因为我们已经在使用它了。
所以在解决方案中…在使用react-intl库的情况下,它们有一个<FormattedRelative>组件。
https://github.com/yahoo/react-intl/wiki/Components#formattedrelative
function dateToHowManyAgo(stringDate){
var currDate = new Date();
var diffMs=currDate.getTime() - new Date(stringDate).getTime();
var sec=diffMs/1000;
if(sec<60)
return parseInt(sec)+' second'+(parseInt(sec)>1?'s':'')+' ago';
var min=sec/60;
if(min<60)
return parseInt(min)+' minute'+(parseInt(min)>1?'s':'')+' ago';
var h=min/60;
if(h<24)
return parseInt(h)+' hour'+(parseInt(h)>1?'s':'')+' ago';
var d=h/24;
if(d<30)
return parseInt(d)+' day'+(parseInt(d)>1?'s':'')+' ago';
var m=d/30;
if(m<12)
return parseInt(m)+' month'+(parseInt(m)>1?'s':'')+' ago';
var y=m/12;
return parseInt(y)+' year'+(parseInt(y)>1?'s':'')+' ago';
}
console.log(dateToHowManyAgo('2019-11-07 19:17:06'));
这是我的版本,它既适用于过去的日期,也适用于未来的日期。 它使用Intl。RelativeTimeFormat提供本地化字符串,而不是硬编码字符串。 您可以将日期作为时间戳、日期对象或可解析的日期字符串传递。
/** * Human readable elapsed or remaining time (example: 3 minutes ago) * @param {Date|Number|String} date A Date object, timestamp or string parsable with Date.parse() * @param {Date|Number|String} [nowDate] A Date object, timestamp or string parsable with Date.parse() * @param {Intl.RelativeTimeFormat} [trf] A Intl formater * @return {string} Human readable elapsed or remaining time * @author github.com/victornpb * @see https://stackoverflow.com/a/67338038/938822 */ function fromNow(date, nowDate = Date.now(), rft = new Intl.RelativeTimeFormat(undefined, { numeric: "auto" })) { const SECOND = 1000; const MINUTE = 60 * SECOND; const HOUR = 60 * MINUTE; const DAY = 24 * HOUR; const WEEK = 7 * DAY; const MONTH = 30 * DAY; const YEAR = 365 * DAY; const intervals = [ { ge: YEAR, divisor: YEAR, unit: 'year' }, { ge: MONTH, divisor: MONTH, unit: 'month' }, { ge: WEEK, divisor: WEEK, unit: 'week' }, { ge: DAY, divisor: DAY, unit: 'day' }, { ge: HOUR, divisor: HOUR, unit: 'hour' }, { ge: MINUTE, divisor: MINUTE, unit: 'minute' }, { ge: 30 * SECOND, divisor: SECOND, unit: 'seconds' }, { ge: 0, divisor: 1, text: 'just now' }, ]; const now = typeof nowDate === 'object' ? nowDate.getTime() : new Date(nowDate).getTime(); const diff = now - (typeof date === 'object' ? date : new Date(date)).getTime(); const diffAbs = Math.abs(diff); for (const interval of intervals) { if (diffAbs >= interval.ge) { const x = Math.round(Math.abs(diff) / interval.divisor); const isFuture = diff < 0; return interval.unit ? rft.format(isFuture ? x : -x, interval.unit) : interval.text; } } }
// examples
fromNow('2020-01-01') // 9 months ago
fromNow(161651684156) // 4 days ago
fromNow(new Date()-1) // just now
fromNow(30000 + Date.now()) // in 30 seconds
fromNow(Date.now() + (1000*60*60*24)) // in 1 day
fromNow(new Date('2029-12-01Z00:00:00.000')) // in 9 years
不使用Intl的替代方法。RelativeTimeFormat
/** * Human readable elapsed or remaining time (example: 3 minutes ago) * @param {Date|Number|String} date A Date object, timestamp or string parsable with Date.parse() * @return {string} Human readable elapsed or remaining time * @author github.com/victornpb * @see https://stackoverflow.com/a/67338038/938822 */ function fromNow(date) { const SECOND = 1000; const MINUTE = 60 * SECOND; const HOUR = 60 * MINUTE; const DAY = 24 * HOUR; const WEEK = 7 * DAY; const MONTH = 30 * DAY; const YEAR = 365 * DAY; const units = [ { max: 30 * SECOND, divisor: 1, past1: 'just now', pastN: 'just now', future1: 'just now', futureN: 'just now' }, { max: MINUTE, divisor: SECOND, past1: 'a second ago', pastN: '# seconds ago', future1: 'in a second', futureN: 'in # seconds' }, { max: HOUR, divisor: MINUTE, past1: 'a minute ago', pastN: '# minutes ago', future1: 'in a minute', futureN: 'in # minutes' }, { max: DAY, divisor: HOUR, past1: 'an hour ago', pastN: '# hours ago', future1: 'in an hour', futureN: 'in # hours' }, { max: WEEK, divisor: DAY, past1: 'yesterday', pastN: '# days ago', future1: 'tomorrow', futureN: 'in # days' }, { max: 4 * WEEK, divisor: WEEK, past1: 'last week', pastN: '# weeks ago', future1: 'in a week', futureN: 'in # weeks' }, { max: YEAR, divisor: MONTH, past1: 'last month', pastN: '# months ago', future1: 'in a month', futureN: 'in # months' }, { max: 100 * YEAR, divisor: YEAR, past1: 'last year', pastN: '# years ago', future1: 'in a year', futureN: 'in # years' }, { max: 1000 * YEAR, divisor: 100 * YEAR, past1: 'last century', pastN: '# centuries ago', future1: 'in a century', futureN: 'in # centuries' }, { max: Infinity, divisor: 1000 * YEAR, past1: 'last millennium', pastN: '# millennia ago', future1: 'in a millennium', futureN: 'in # millennia' }, ]; const diff = Date.now() - (typeof date === 'object' ? date : new Date(date)).getTime(); const diffAbs = Math.abs(diff); for (const unit of units) { if (diffAbs < unit.max) { const isFuture = diff < 0; const x = Math.round(Math.abs(diff) / unit.divisor); if (x <= 1) return isFuture ? unit.future1 : unit.past1; return (isFuture ? unit.futureN : unit.pastN).replace('#', x); } } };
Lokely使用的一个简短版本:
const intervals = [
{ label: 'year', seconds: 31536000 },
{ label: 'month', seconds: 2592000 },
{ label: 'day', seconds: 86400 },
{ label: 'hour', seconds: 3600 },
{ label: 'minute', seconds: 60 },
{ label: 'second', seconds: 1 }
];
function timeSince(date) {
const seconds = Math.floor((Date.now() - date.getTime()) / 1000);
const interval = intervals.find(i => i.seconds < seconds);
const count = Math.floor(seconds / interval.seconds);
return `${count} ${interval.label}${count !== 1 ? 's' : ''} ago`;
}