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

e.g.

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


当前回答

我的解决方案。

(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)')));

其他回答

由@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编辑建议。(谢谢!)

要使用这个,只需复制所有这些代码,并将其导入到你的组件或任何地方,并将你的ISOstring()日期放在:showTimeAgo("2022-06-20T13:42:29-05:00"),你将获得每个场景的自动时间更新。

旁注:我为这个https://www.npmjs.com/package/showtimeago做了一个npm包

export const showTimeAgo = () => {
    const MONTH_NAMES = [
        'January',
        'February',
        'March',
        'April',
        'May',
        'June',
        'July',
        'August',
        'September',
        'October',
        'November',
        'December',
    ];

    function getOrdinalNum() {
        return (
            n +
            (n > 0
                ? ['th', 'st', 'nd', 'rd'][
                      (n > 3 && n < 21) || n % 10 > 3 ? 0 : n % 10
                  ]
                : '')
        );
    }

    function getFormattedDate(
        date,
        preformattedDate = false,
        hideYear = false
    ) {
        const day = date.getDate();
        const month = MONTH_NAMES[date.getMonth()];
        const year = date.getFullYear();
        let hours = date.getHours();
        let minutes = date.getMinutes();

        let ampm = hours >= 12 ? 'pm' : 'am';

        switch(true){
            case (hours > 12):
                hours = hours - 12;
                break;
            case (hours === 0):
                hours = 12;
                break;
            case(minutes < 10):
                minutes = `0${minutes}`;
                break;
            case(preformattedDate):
            // Today at 10:20am
            // Yesterday at 10:20am
                return `${preformattedDate} at ${hours}:${minutes} ${ampm}`;

            case(hideYear):
                // January 10th at 10:20pm
                return `${month} ${getOrdinalNum(
                    day
                )}, at ${hours}:${minutes} ${ampm}`;
            default:
                // January 10th 2022 at 10:20pm
                return `${month} ${getOrdinalNum(
                    day
                )}, ${year} at ${hours}:${minutes} ${ampm}`;
        }
        
    }

    // --- Main function
    function timeAgo(dateParam) {
        if (!dateParam) {
            return null;
        }

        const date =
            typeof dateParam === 'object' ? dateParam : new Date(dateParam);
        const DAY_IN_MS = 86400000; // 24 * 60 * 60 * 1000
        const today = new Date();

        const yesterday = new Date(today - DAY_IN_MS);

        const seconds = Math.round((today - date) / 1000);
        const minutes = Math.round(seconds / 60);
        const hour = Math.round(seconds / 3600);
        const day = Math.round(seconds / 86400);
        const month = Math.round(seconds / 2629800);
        const year = Math.floor(seconds / 31536000);
        const isToday = today.toDateString() === date.toDateString();
        const isYesterday =
            yesterday.toDateString() === date.toDateString();
        const isThisYear = today.getFullYear() === date.getFullYear();

        switch(true){
            case (seconds < 5):
                return 'now';
            case (seconds < 60):
                return `${seconds} seconds ago`;
            case (seconds < 90):
                return 'about a minute ago';
            case (minutes < 60):
                return `${minutes} minutes ago`;
            case (hour === 1 && hour < 2):
                return `${hour} hour ago`; // 1 hour ago
            case (hour > 1 && hour <= 12):
                return `${hour} hours ago`; // 2 hours ago
            case (isToday):
                return getFormattedDate(date, 'Today'); // Today at 10:20am
            case (isYesterday): 
                return getFormattedDate(date, 'Yesterday'); // Yesterday at 10:20am
            case(day > 1 && day <= 30):
                return `${day} days ago`; // 2 days ago
            case (isThisYear):
                return getFormattedDate(date, false, true); // January 10th at 10:20pm 
            case (day > 30 && month <= 1):
                return `${hour} month ago`; // 1 month ago
            case (month > 1 && month <= 12):
                return `${month} months ago`; // 2 months ago
            case (year === 1):
                return `${year} year ago`; // 1 year ago
            case (year > 1):
                return `${year} years ago`; // 2 years ago
            default:
                return getFormattedDate(date); // January 10th 2022 at 10:20pm
        }
    }

    return timeAgo(date);
};

console.log(showTimeAgo("2022-06-20T13:42:29-05:00"));-05:00"))

我用js和python写了一个,在两个项目中使用,非常漂亮和简单:一个简单的库(少于2kb),用于*** time ago语句格式化日期。

简单,小巧,易于使用,并且经过良好测试。

NPM安装timeago.js 从timeago.js导入timeago;//或使用脚本标签 使用API格式。

示例:

var timeagoIns  = timeago();
timeagoIns .format('2016-06-12');

你也可以实时渲染。

var timeagoIns = timeago();
timeagoIns.render(document.querySelectorAll('time'));

可读性强且跨浏览器兼容的代码:

@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'));

    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'))