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

后端 未结 25 1592
遥遥无期
遥遥无期 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:29

    This will show you past and previous time formats like '2 days ago' '10 minutes from now' and you can pass it either a Date object, a numeric timestamp or a date string

    function time_ago(time) {
    
      switch (typeof time) {
        case 'number':
          break;
        case 'string':
          time = +new Date(time);
          break;
        case 'object':
          if (time.constructor === Date) time = time.getTime();
          break;
        default:
          time = +new Date();
      }
      var time_formats = [
        [60, 'seconds', 1], // 60
        [120, '1 minute ago', '1 minute from now'], // 60*2
        [3600, 'minutes', 60], // 60*60, 60
        [7200, '1 hour ago', '1 hour from now'], // 60*60*2
        [86400, 'hours', 3600], // 60*60*24, 60*60
        [172800, 'Yesterday', 'Tomorrow'], // 60*60*24*2
        [604800, 'days', 86400], // 60*60*24*7, 60*60*24
        [1209600, 'Last week', 'Next week'], // 60*60*24*7*4*2
        [2419200, 'weeks', 604800], // 60*60*24*7*4, 60*60*24*7
        [4838400, 'Last month', 'Next month'], // 60*60*24*7*4*2
        [29030400, 'months', 2419200], // 60*60*24*7*4*12, 60*60*24*7*4
        [58060800, 'Last year', 'Next year'], // 60*60*24*7*4*12*2
        [2903040000, 'years', 29030400], // 60*60*24*7*4*12*100, 60*60*24*7*4*12
        [5806080000, 'Last century', 'Next century'], // 60*60*24*7*4*12*100*2
        [58060800000, 'centuries', 2903040000] // 60*60*24*7*4*12*100*20, 60*60*24*7*4*12*100
      ];
      var seconds = (+new Date() - time) / 1000,
        token = 'ago',
        list_choice = 1;
    
      if (seconds == 0) {
        return 'Just now'
      }
      if (seconds < 0) {
        seconds = Math.abs(seconds);
        token = 'from now';
        list_choice = 2;
      }
      var i = 0,
        format;
      while (format = time_formats[i++])
        if (seconds < format[0]) {
          if (typeof format[2] == 'string')
            return format[list_choice];
          else
            return Math.floor(seconds / format[2]) + ' ' + format[1] + ' ' + token;
        }
      return time;
    }
    
    var aDay = 24 * 60 * 60 * 1000;
    console.log(time_ago(new Date(Date.now() - aDay)));
    console.log(time_ago(new Date(Date.now() - aDay * 2)));

    0 讨论(0)
  • 2020-11-22 13:29
    function timeago(date) {
        var seconds = Math.floor((new Date() - date) / 1000);
        if(Math.round(seconds/(60*60*24*365.25)) >= 2) return Math.round(seconds/(60*60*24*365.25)) + " years ago";
        else if(Math.round(seconds/(60*60*24*365.25)) >= 1) return "1 year ago";
        else if(Math.round(seconds/(60*60*24*30.4)) >= 2) return Math.round(seconds/(60*60*24*30.4)) + " months ago";
        else if(Math.round(seconds/(60*60*24*30.4)) >= 1) return "1 month ago";
        else if(Math.round(seconds/(60*60*24*7)) >= 2) return Math.round(seconds/(60*60*24*7)) + " weeks ago";
        else if(Math.round(seconds/(60*60*24*7)) >= 1) return "1 week ago";
        else if(Math.round(seconds/(60*60*24)) >= 2) return Math.round(seconds/(60*60*24)) + " days ago";
        else if(Math.round(seconds/(60*60*24)) >= 1) return "1 day ago";
        else if(Math.round(seconds/(60*60)) >= 2) return Math.round(seconds/(60*60)) + " hours ago";
        else if(Math.round(seconds/(60*60)) >= 1) return "1 hour ago";
        else if(Math.round(seconds/60) >= 2) return Math.round(seconds/60) + " minutes ago";
        else if(Math.round(seconds/60) >= 1) return "1 minute ago";
        else if(seconds >= 2)return seconds + " seconds ago";
        else return seconds + "1 second ago";
    }
    
    0 讨论(0)
  • 2020-11-22 13:29

    My solution..

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

    My stab at this based on other answers.

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

    I haven't checked (although it wouldn't be hard to), but I think that Stack Exchange sites use the jquery.timeago plugin to create these time strings.


    It's quite easy to use the plugin, and it's clean and updates automatically.

    Here's a quick sample (from the plugin's home page):

    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.

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

    Here's what I did (the object returns the unit of time along with its value):

    function timeSince(post_date, reference)
    {
    	var reference = reference ? new Date(reference) : new Date(),
    		diff = reference - new Date(post_date + ' GMT-0000'),
    		date = new Date(diff),
    		object = { unit: null, value: null };
    	
    	if (diff < 86400000)
    	{
    		var secs  = date.getSeconds(),
    			mins  = date.getMinutes(),
    			hours = date.getHours(),
    			array = [ ['second', secs], ['minute', mins], ['hour', hours] ];
    	}
    	else
    	{
    		var days   = date.getDate(),
    			weeks  = Math.floor(days / 7),
    			months = date.getMonth(),
    			years  = date.getFullYear() - 1970,
    			array  = [ ['day', days], ['week', weeks], ['month', months], ['year', years] ];
    	}
    
    	for (var i = 0; i < array.length; i++)
    	{
    		array[i][0] += array[i][1] != 1 ? 's' : '';
    
    		object.unit  = array[i][1] >= 1 ? array[i][0] : object.unit;
    		object.value = array[i][1] >= 1 ? array[i][1] : object.value;
    	}
    
    	return object;
    }

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