How to format time since xxx e.g. “4 minutes ago” similar to Stack Exchange sites

后端 未结 25 1593
遥遥无期
遥遥无期 2020-11-22 12:57

The question is how to format a JavaScript Date as a string stating the time elapsed similar to the way you see times displayed on Stack Overflow.

e.g.<

相关标签:
25条回答
  • 2020-11-22 13:20

    Much readable and cross browser compatible code:

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

    0 讨论(0)
  • 2020-11-22 13:20

    This should properly handle any valid timestamp, including Date.now(), singular units, and future dates. I left out months, but those should be easy to add in. I tried to keep it readable as possible.

    function getTimeInterval(date) {
      let seconds = Math.floor((Date.now() - date) / 1000);
      let unit = "second";
      let direction = "ago";
      if (seconds < 0) {
        seconds = -seconds;
        direction = "from now";
      }
      let value = seconds;
      if (seconds >= 31536000) {
        value = Math.floor(seconds / 31536000);
        unit = "year";
      } else if (seconds >= 86400) {
        value = Math.floor(seconds / 86400);
        unit = "day";
      } else if (seconds >= 3600) {
        value = Math.floor(seconds / 3600);
        unit = "hour";
      } else if (seconds >= 60) {
        value = Math.floor(seconds / 60);
        unit = "minute";
      }
      if (value != 1)
        unit = unit + "s";
      return value + " " + unit + " " + direction;
    }
    
    console.log(getTimeInterval(Date.now())); // 0 seconds ago
    console.log(getTimeInterval(Date.now() + 1000)); // 1 second from now
    console.log(getTimeInterval(Date.now() - 1000)); // 1 second ago
    console.log(getTimeInterval(Date.now() + 60000)); // 1 minute from now
    console.log(getTimeInterval(Date.now() - 120000)); // 2 minutes ago
    console.log(getTimeInterval(Date.now() + 120000)); // 2 minutes from now
    console.log(getTimeInterval(Date.now() + 3600000)); // 1 hour from now
    console.log(getTimeInterval(Date.now() + 360000000000)); // 11 years from now
    console.log(getTimeInterval(0)); // 49 years ago

    0 讨论(0)
  • 2020-11-22 13:22
     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')));
    
    0 讨论(0)
  • 2020-11-22 13:23

    I was looking for an answer to this and almost implemented one of these solutions, but a colleague reminded me to check the react-intl library since we were already using it.

    So adding to the solutions...in the case you are using the react-intl library, they have a <FormattedRelative> component for this.

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

    0 讨论(0)
  • 2020-11-22 13:25

    A shorter version as used by 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: 0 }
    ];
    
    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`;
    }
    
    0 讨论(0)
  • 2020-11-22 13:26

    Here is a slight modification on Sky Sander's solution that allows the date to be input as a string and is capable of displaying spans like "1 minute" instead of "73 seconds"

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

    0 讨论(0)
提交回复
热议问题