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

e.g.

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


当前回答

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

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

其他回答

这些答案大多不能解释复数(例如:复数)。当我们想要“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
// ...

我一直在寻找这个问题的答案,并且几乎实现了其中一个解决方案,但一位同事提醒我检查react-intl库,因为我们已经在使用它了。

所以在解决方案中…在使用react-intl库的情况下,它们有一个<FormattedRelative>组件。

https://github.com/yahoo/react-intl/wiki/Components#formattedrelative

function timeSince(date) { var seconds = Math.floor((new Date() - date) / 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"; } var aDay = 24*60*60*1000; console.log(timeSince(new Date(Date.now()-aDay))); console.log(timeSince(new Date(Date.now()-aDay*2)));

我还没有检查(虽然这并不难),但我认为Stack Exchange站点使用jquery。Timeago插件来创建这些时间字符串。


这个插件使用起来很简单,而且很干净,还能自动更新。

下面是一个简单的例子(来自插件的主页):

First, load jQuery and the plugin: <script src="jquery.min.js" type="text/javascript"></script> <script src="jquery.timeago.js" type="text/javascript"></script> Now, let's attach it to your timestamps on DOM ready: jQuery(document).ready(function() { jQuery("abbr.timeago").timeago(); }); This will turn all abbr elements with a class of timeago and an ISO 8601 timestamp in the title: <abbr class="timeago" title="2008-07-17T09:24:17Z">July 17, 2008</abbr> into something like this: <abbr class="timeago" title="July 17, 2008">about a year ago</abbr> which yields: about a year ago. As time passes, the timestamps will automatically update.

 I achieve this by following method

   timeAgo = (date) => {
            var ms = (new Date()).getTime() - date.getTime();
            var seconds = Math.floor(ms / 1000);
            var minutes = Math.floor(seconds / 60);
        var hours = Math.floor(minutes / 60);
        var days = Math.floor(hours / 24);
        var months = Math.floor(days / 30);
        var years = Math.floor(months / 12);
    
        if (ms === 0) {
            return 'Just now';
        } if (seconds < 60) {
            return seconds + ' seconds Ago';
        } if (minutes < 60) {
            return minutes + ' minutes Ago';
        } if (hours < 24) {
            return hours + ' hours Ago';
        } if (days < 30) {
            return days + ' days Ago';
        } if (months < 12) {
            return months + ' months Ago';
        } else {
            return years + ' years Ago';
        }
    
    }
    
        console.log(timeAgo(new Date()));
        console.log(timeAgo(new Date('Jun 27 2020 10:12:19')));
        console.log(timeAgo(new Date('Jun 27 2020 00:12:19')));
        console.log(timeAgo(new Date('May 28 2020 13:12:19')));
        console.log(timeAgo(new Date('May 28 2017 13:12:19')));