问题是如何将JavaScript Date格式化为一个字符串,声明时间经过,类似于您在Stack Overflow上看到的时间显示方式。

e.g.

1分钟前 1小时前 1天前 1个月前 一年前


当前回答

从现在开始,Unix时间戳参数

function timeSince(ts){
    now = new Date();
    ts = new Date(ts*1000);
    var delta = now.getTime() - ts.getTime();

    delta = delta/1000; //us to s

    var ps, pm, ph, pd, min, hou, sec, days;

    if(delta<=59){
        ps = (delta>1) ? "s": "";
        return delta+" second"+ps
    }

    if(delta>=60 && delta<=3599){
        min = Math.floor(delta/60);
        sec = delta-(min*60);
        pm = (min>1) ? "s": "";
        ps = (sec>1) ? "s": "";
        return min+" minute"+pm+" "+sec+" second"+ps;
    }

    if(delta>=3600 && delta<=86399){
        hou = Math.floor(delta/3600);
        min = Math.floor((delta-(hou*3600))/60);
        ph = (hou>1) ? "s": "";
        pm = (min>1) ? "s": "";
        return hou+" hour"+ph+" "+min+" minute"+pm;
    } 

    if(delta>=86400){
        days = Math.floor(delta/86400);
        hou =  Math.floor((delta-(days*86400))/60/60);
        pd = (days>1) ? "s": "";
        ph = (hou>1) ? "s": "";
        return days+" day"+pd+" "+hou+" hour"+ph;
    }

}

其他回答

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`;
}

这是对国际的另一种看法。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

这是我的版本,它既适用于过去的日期,也适用于未来的日期。 它使用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); } } };

你可以使用Luxon:

DateTime.toRelative()

https://moment.github.io/luxon/api-docs/index.html#datetimetorelative

这里还有一些例子:

const DateTime = luxon.DateTime; // toRelative console.log(DateTime.now().minus({ seconds: 1 }).toRelative()) // 1 second ago console.log(DateTime.now().minus({ seconds: 10 }).toRelative()) // 10 seconds ago console.log(DateTime.now().minus({ days: 2 }).toRelative()) console.log(DateTime.now().minus({ years: 3 }).toRelative()) console.log(DateTime.now().plus({ years: 3 }).toRelative()) console.log(DateTime.now().plus({ days: 2 }).toRelative()) console.log(DateTime.now().plus({ seconds: 1 }).toRelative()) console.log(DateTime.now().plus({ seconds: 10 }).toRelative()) // toRelativeCalendar console.log(DateTime.now().minus({ seconds: 1 }).toRelativeCalendar()) // today console.log(DateTime.now().minus({ seconds: 10 }).toRelativeCalendar()) // today console.log(DateTime.now().minus({ days: 2 }).toRelativeCalendar()) console.log(DateTime.now().minus({ years: 3 }).toRelativeCalendar()) console.log(DateTime.now().plus({ years: 3 }).toRelativeCalendar()) console.log(DateTime.now().plus({ days: 2 }).toRelativeCalendar()) console.log(DateTime.now().plus({ seconds: 1 }).toRelativeCalendar()) console.log(DateTime.now().plus({ seconds: 10 }).toRelativeCalendar()) <script src="https://moment.github.io/luxon/global/luxon.min.js"></script>

    const timeHandler = (time: any) => {
      var a = moment(); //now
      var b = moment.utc(time);
      const sec = a.diff(b, 'seconds');
      const minuts = a.diff(b, 'minutes');
      const hours = a.diff(b, 'hours');
      const days = a.diff(b, 'days');
      const weeks = a.diff(b, 'weeks');
      return weeks == 0
        ? days == 0
          ? hours == 0
            ? minuts == 0
              ? sec >= 0 && `${sec}s ago`
              : `${minuts}m ago`
            : `${hours}h ago`
          : `${days}d ago`
        : `${weeks}w ago`;
    };

console.log(timeHandler('2022-11-11T12:11:06.6103808'))