Javascript 如何格式化自 xxx 以来的时间,例如“4 分钟前”,类似于 Stack Exchange 站点

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3177836/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 03:33:51  来源:igfitidea点击:

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

javascriptdate-formatting

提问by Sky Sanders

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

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

e.g.

例如

  • 1 minute ago
  • 1 hour ago
  • 1 day ago
  • 1 month ago
  • 1 year ago
  • 1 分钟前
  • 1小时前
  • 1天前
  • 1个月前
  • 1年前

回答by Sky Sanders

function timeSince(date) {

  var seconds = Math.floor((new Date() - date) / 1000);

  var interval = Math.floor(seconds / 31536000);

  if (interval > 1) {
    return interval + " years";
  }
  interval = Math.floor(seconds / 2592000);
  if (interval > 1) {
    return interval + " months";
  }
  interval = Math.floor(seconds / 86400);
  if (interval > 1) {
    return interval + " days";
  }
  interval = Math.floor(seconds / 3600);
  if (interval > 1) {
    return interval + " hours";
  }
  interval = Math.floor(seconds / 60);
  if (interval > 1) {
    return 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)));

回答by Fabiano Soriani

Might be an overkill in this case, but if the opportunity shows moment.jsis just awesome!

在这种情况下可能有点矫枉过正,但如果机会表明moment.js真是太棒了!

Moment.js is a javascript datetime library, to use it for such scenario, you'd do:

Moment.js 是一个 javascript 日期时间库,要将它用于这种情况,您需要执行以下操作:

moment(yourdate).fromNow()

http://momentjs.com/docs/#/displaying/fromnow/

http://momentjs.com/docs/#/displaying/fromnow/

2018 addendum: Luxonis a new modern library and might be worth a look!

2018 年附录Luxon是一个新的现代图书馆,值得一看!

回答by Maxim Zaslavsky

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

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



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 abbrelements with a class of timeagoand 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.

首先,加载 jQuery 和插件:

<script src="jquery.min.js" type="text/javascript"></script> <script src="jquery.timeago.js" type="text/javascript"></script>

现在,让我们将它附加到 DOM 上的时间戳上:

jQuery(document).ready(function() {
jQuery("abbr.timeago").timeago(); });

这会将标题中abbr具有类timeago和 ISO 8601 时间戳的所有元素:<abbr class="timeago" title="2008-07-17T09:24:17Z">July 17, 2008</abbr>变成这样的: <abbr class="timeago" title="July 17, 2008">about a year ago</abbr>产生:大约一年前。随着时间的推移,时间戳会自动更新。

回答by TheBrain

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

这将显示过去和以前的时间格式,例如“2 天前”“从现在起 10 分钟”,您可以将它传递给 Date 对象、数字时间戳或日期字符串

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

回答by rob

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"

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

回答by Will Tomlins

You might want to look at humanized_time_span: https://github.com/layam/js_humanized_time_span

你可能想看看humanized_time_span:https: //github.com/layam/js_humanized_time_span

It's framework agnostic and fully customizable.

它与框架无关且完全可定制。

Just download / include the script and then you can do this:

只需下载/包含脚本,然后您就可以执行以下操作:

humanized_time_span("2011-05-11 12:00:00")  
   => '3 hours ago'

humanized_time_span("2011-05-11 12:00:00", "2011-05-11 16:00:00)  
   => '4 hours ago'

or even this:

甚至这个:

var custom_date_formats = {
  past: [
    { ceiling: 60, text: "less than a minute ago" },
    { ceiling: 86400, text: "$hours hours, $minutes minutes and $seconds seconds ago" },
    { ceiling: null, text: "$years years ago" }
  ],
  future: [
    { ceiling: 60, text: "in less than a minute" },
    { ceiling: 86400, text: "in $hours hours, $minutes minutes and $seconds seconds time" },
    { ceiling: null, text: "in $years years" }
  ]
}

humanized_time_span("2010/09/10 10:00:00", "2010/09/10 10:00:05", custom_date_formats) 
  => "less than a minute ago"

Read the docs for more info.

阅读文档了解更多信息。

回答by PanMan

Changed the function above to

将上面的函数改为

function timeSince(date) {

    var seconds = Math.floor(((new Date().getTime()/1000) - date)),
    interval = Math.floor(seconds / 31536000);

    if (interval > 1) return interval + "y";

    interval = Math.floor(seconds / 2592000);
    if (interval > 1) return interval + "m";

    interval = Math.floor(seconds / 86400);
    if (interval >= 1) return interval + "d";

    interval = Math.floor(seconds / 3600);
    if (interval >= 1) return interval + "h";

    interval = Math.floor(seconds / 60);
    if (interval > 1) return interval + "m ";

    return Math.floor(seconds) + "s";
}

Otherwise it would show things like "75 minutes" (between 1 and 2 hours). It also now assumes input date is a Unix timestamp.

否则,它会显示“75 分钟”(1 到 2 小时之间)之类的内容。它现在还假定输入日期是 Unix 时间戳。

回答by user1012181

Much readable and cross browser compatible code:

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

As given by @Travis

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

回答by Sam

A shorter version as used by Lokely:

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`;
}

回答by pkarc

from now, unix timestamp param,

从现在开始,unix 时间戳参数,

function timeSince(ts){
    now = new Date();
    ts = new Date(ts*1000);
    var delta = now.getTime() - ts.getTime();

    delta = delta/1000; //us to s

    var ps, pm, ph, pd, min, hou, sec, days;

    if(delta<=59){
        ps = (delta>1) ? "s": "";
        return delta+" second"+ps
    }

    if(delta>=60 && delta<=3599){
        min = Math.floor(delta/60);
        sec = delta-(min*60);
        pm = (min>1) ? "s": "";
        ps = (sec>1) ? "s": "";
        return min+" minute"+pm+" "+sec+" second"+ps;
    }

    if(delta>=3600 && delta<=86399){
        hou = Math.floor(delta/3600);
        min = Math.floor((delta-(hou*3600))/60);
        ph = (hou>1) ? "s": "";
        pm = (min>1) ? "s": "";
        return hou+" hour"+ph+" "+min+" minute"+pm;
    } 

    if(delta>=86400){
        days = Math.floor(delta/86400);
        hou =  Math.floor((delta-(days*86400))/60/60);
        pd = (days>1) ? "s": "";
        ph = (hou>1) ? "s": "";
        return days+" day"+pd+" "+hou+" hour"+ph;
    }

}