问题是如何将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)')));

其他回答

以下是对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)));

function mdiv(dividend, divisor) {
    return [ Math.floor(dividend/divisor), dividend % divisor ];
}
// pass in milliseconds, gained by Date1.getTime() - Date2.getTime()
// if max_units is two, the result will be, for example
// 2years 12months ago, or 2hours 38minutes ago
// return formated period

function readable_period(ms, max_units=2){
    let [yy, yr] = mdiv(ms, 3.154e10);
    let [mm, mr] = mdiv(yr, 2.628e9);
    let [dd, dr] = mdiv(mr, 8.64e7);
    let [hh, hr] = mdiv(dr, 3.6e6);
    let [tt, ss] = mdiv(hr, 6e4);

    var ymdht = ['year', 'month', 'day', 'hour', 'minute'];
    let res = [];
    [yy, mm, dd, hh, tt].forEach((tis, ii)=>{
        if(res.length === max_units){return};
        if(tis !== 0){
            res.push(tis === 1 ? `${tis}${ymdht[ii]}` : `${tis}${ymdht[ii]}s`);
        }
    });
    return res.length === 0 ? '' : res.join(' ') + ' ago';
}

如果你已经在使用date-fns,你可以使用内置的formatDistance(以前是distanceInWords):

const date1 = new Date(2014, 6, 2);
const date2 = new Date(2015, 0, 1);
const options = { addSuffix: true }
const result = formatDistance(date1, date2, options);
//=> '6 months ago'

这些答案大多不能解释复数(例如:复数)。当我们想要“1分钟前”时,用“1分钟前”)

const MINUTE = 60;
const HOUR = MINUTE * 60;
const DAY = HOUR * 24;
const WEEK = DAY * 7;
const MONTH = DAY * 30;
const YEAR = DAY * 365;

function getTimeAgo(date) {
  const secondsAgo = Math.round((Date.now() - Number(date)) / 1000);

  if (secondsAgo < MINUTE) {
    return secondsAgo + ` second${secondsAgo !== 1 ? "s" : ""} ago`;
  }

  let divisor;
  let unit = "";

  if (secondsAgo < HOUR) {
    [divisor, unit] = [MINUTE, "minute"];
  } else if (secondsAgo < DAY) {
    [divisor, unit] = [HOUR, "hour"];
  } else if (secondsAgo < WEEK) {
    [divisor, unit] = [DAY, "day"];
  } else if (secondsAgo < MONTH) {
    [divisor, unit] = [WEEK, "week"];
  } else if (secondsAgo < YEAR) {
    [divisor, unit] = [MONTH, "month"];
  } else {
    [divisor, unit] = [YEAR, "year"];
  }

  const count = Math.floor(secondsAgo / divisor);
  return `${count} ${unit}${count > 1 ? "s" : ""} ago`;
}

然后你可以这样使用它:

const date = new Date();
console.log(getTimeAgo(date));
// 1 second ago
// 2 seconds ago
// 1 minute ago
// 2 minutes ago
// ...

以上答案适用于旧的java脚本。但它在新的EC6 JavaScript或TypeScript上运行得不太好。下面是一个非常简短和简单的函数,用于最新的JavaScript, TypeScript, AngularJs, ReactJs和NodeJs,根据给定的日期和时间返回时间。

  public timeAgo(date) {
    var seconds = Math.floor((new Date().getTime() - new Date(date).getTime()) / 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";
  }

console.log(timeAgo('2022-08-12 20:50:20'));
// 2 hours ago, as per the given date time string.