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

e.g.

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


当前回答

我的尝试是基于其他的答案。

function timeSince(date) {
    let minute = 60;
    let hour   = minute * 60;
    let day    = hour   * 24;
    let month  = day    * 30;
    let year   = day    * 365;

    let suffix = ' ago';

    let elapsed = Math.floor((Date.now() - date) / 1000);

    if (elapsed < minute) {
        return 'just now';
    }

    // get an array in the form of [number, string]
    let a = elapsed < hour  && [Math.floor(elapsed / minute), 'minute'] ||
            elapsed < day   && [Math.floor(elapsed / hour), 'hour']     ||
            elapsed < month && [Math.floor(elapsed / day), 'day']       ||
            elapsed < year  && [Math.floor(elapsed / month), 'month']   ||
            [Math.floor(elapsed / year), 'year'];

    // pluralise and append suffix
    return a[0] + ' ' + a[1] + (a[0] === 1 ? '' : 's') + suffix;
}

其他回答

以下是对Sky Sander的解决方案的轻微修改,允许日期作为字符串输入,并能够显示像“1分钟”而不是“73秒”这样的跨度

var timeSince = function(date) { if (typeof date !== 'object') { date = new Date(date); } var seconds = Math.floor((new Date() - date) / 1000); var intervalType; var interval = Math.floor(seconds / 31536000); if (interval >= 1) { intervalType = 'year'; } else { interval = Math.floor(seconds / 2592000); if (interval >= 1) { intervalType = 'month'; } else { interval = Math.floor(seconds / 86400); if (interval >= 1) { intervalType = 'day'; } else { interval = Math.floor(seconds / 3600); if (interval >= 1) { intervalType = "hour"; } else { interval = Math.floor(seconds / 60); if (interval >= 1) { intervalType = "minute"; } else { interval = seconds; intervalType = "second"; } } } } } if (interval > 1 || interval === 0) { intervalType += 's'; } return interval + ' ' + intervalType; }; 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++]); } } }

也可以使用dayjs的relativeTime插件来解决这个问题。

import * as dayjs from 'dayjs';
import * as relativeTime from 'dayjs/plugin/relativeTime';

dayjs.extend(relativeTime);
dayjs(dayjs('1990')).fromNow(); // x years ago
    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'))

我的解决方案。

(function(global){
            const SECOND   = 1;
            const MINUTE   = 60;
            const HOUR     = 3600;
            const DAY      = 86400;
            const MONTH    = 2629746;
            const YEAR     = 31556952;
            const DECADE   = 315569520;

            global.timeAgo = function(date){
                var now = new Date();
                var diff = Math.round(( now - date ) / 1000);

                var unit = '';
                var num = 0;
                var plural = false;

                switch(true){
                    case diff <= 0:
                        return 'just now';
                    break;

                    case diff < MINUTE:
                        num = Math.round(diff / SECOND);
                        unit = 'sec';
                        plural = num > 1;
                    break;

                    case diff < HOUR:
                        num = Math.round(diff / MINUTE);
                        unit = 'min';
                        plural = num > 1;
                    break;

                    case diff < DAY:
                        num = Math.round(diff / HOUR);
                        unit = 'hour';
                        plural = num > 1;
                    break;

                    case diff < MONTH:
                        num = Math.round(diff / DAY);
                        unit = 'day';
                        plural = num > 1;
                    break;

                    case diff < YEAR:
                        num = Math.round(diff / MONTH);
                        unit = 'month';
                        plural = num > 1;
                    break;

                    case diff < DECADE:
                        num = Math.round(diff / YEAR);
                        unit = 'year';
                        plural = num > 1;
                    break;

                    default:
                        num = Math.round(diff / YEAR);
                        unit = 'year';
                        plural = num > 1;
                }

                var str = '';
                if(num){
                    str += `${num} `;
                }

                str += `${unit}`;

                if(plural){
                    str += 's';
                }

                str += ' ago';

                return str;
            }
        })(window);

        console.log(timeAgo(new Date()));
        console.log(timeAgo(new Date('Jun 03 2018 15:12:19 GMT+0300 (FLE Daylight Time)')));
        console.log(timeAgo(new Date('Jun 03 2018 13:12:19 GMT+0300 (FLE Daylight Time)')));
        console.log(timeAgo(new Date('May 28 2018 13:12:19 GMT+0300 (FLE Daylight Time)')));
        console.log(timeAgo(new Date('May 28 2017 13:12:19 GMT+0300 (FLE Daylight Time)')));
        console.log(timeAgo(new Date('May 28 2000 13:12:19 GMT+0300 (FLE Daylight Time)')));
        console.log(timeAgo(new Date('Sep 10 1994 13:12:19 GMT+0300 (FLE Daylight Time)')));