289

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

例如

  • 1 分钟前
  • 1小时前
  • 1天前
  • 1个月前
  • 1年前
4

31 回答 31

407

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

于 2010-07-05T07:45:51.093 回答
155

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

Moment.js 是一个 javascript 日期时间库,要在这种情况下使用它,您可以:

moment(yourdate).fromNow()

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

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

于 2013-04-16T16:50:46.090 回答
72

这将向您显示过去和以前的时间格式,例如“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)));

于 2012-09-18T10:35:32.083 回答
57

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


该插件非常易于使用,并且干净且自动更新。

这是一个快速示例(来自插件的主页):

首先,加载 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具有类和 ISO 8601 时间戳的所有元素转换为 : 大约一年前。随着时间的推移,时间戳会自动更新。timeago<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>

于 2010-07-05T07:59:05.950 回答
28

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

于 2014-04-24T03:30:12.853 回答
18

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: 1 }
];

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`;
}
于 2017-10-29T23:40:48.817 回答
15

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

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

只需下载/包含脚本,然后您就可以这样做:

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'

甚至这个:

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"

阅读文档以获取更多信息。

于 2011-05-11T14:30:37.523 回答
15

@user1012181 提供的代码的 ES6 版本:

const epochs = [
    ['year', 31536000],
    ['month', 2592000],
    ['day', 86400],
    ['hour', 3600],
    ['minute', 60],
    ['second', 1]
];

const getDuration = (timeAgoInSeconds) => {
    for (let [name, seconds] of epochs) {
        const interval = Math.floor(timeAgoInSeconds / seconds);
        if (interval >= 1) {
            return {
                interval: interval,
                epoch: name
            };
        }
    }
};

const timeAgo = (date) => {
    const timeAgoInSeconds = Math.floor((new Date() - new Date(date)) / 1000);
    const {interval, epoch} = getDuration(timeAgoInSeconds);
    const suffix = interval === 1 ? '' : 's';
    return `${interval} ${epoch}${suffix} ago`;
};

使用@ibe-vanmeenen 建议进行编辑。(谢谢!)

于 2015-11-02T21:28:55.190 回答
14

将上面的功能更改为

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

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

于 2011-11-23T18:13:53.600 回答
12

所以这是我的版本,它适用于过去和未来的日期。它使用Intl.RelativeTimeFormat提供本地化字符串,而不是硬编码字符串。您可以将日期作为时间戳、日期对象或可解析的日期字符串传递。

/**
 * Human readable elapsed or remaining time (example: 3 minutes ago)
 * @param  {Date|Number|String} date A Date object, timestamp or string parsable with Date.parse()
 * @param  {Date|Number|String} [nowDate] A Date object, timestamp or string parsable with Date.parse()
 * @param  {Intl.RelativeTimeFormat} [trf] A Intl formater
 * @return {string} Human readable elapsed or remaining time
 * @author github.com/victornpb
 * @see https://stackoverflow.com/a/67338038/938822
 */
function fromNow(date, nowDate = Date.now(), rft = new Intl.RelativeTimeFormat(undefined, { numeric: "auto" })) {
    const SECOND = 1000;
    const MINUTE = 60 * SECOND;
    const HOUR = 60 * MINUTE;
    const DAY = 24 * HOUR;
    const WEEK = 7 * DAY;
    const MONTH = 30 * DAY;
    const YEAR = 365 * DAY;
    const intervals = [
        { ge: YEAR, divisor: YEAR, unit: 'year' },
        { ge: MONTH, divisor: MONTH, unit: 'month' },
        { ge: WEEK, divisor: WEEK, unit: 'week' },
        { ge: DAY, divisor: DAY, unit: 'day' },
        { ge: HOUR, divisor: HOUR, unit: 'hour' },
        { ge: MINUTE, divisor: MINUTE, unit: 'minute' },
        { ge: 30 * SECOND, divisor: SECOND, unit: 'seconds' },
        { ge: 0, divisor: 1, text: 'just now' },
    ];
    const now = typeof nowDate === 'object' ? nowDate.getTime() : new Date(nowDate).getTime();
    const diff = now - (typeof date === 'object' ? date : new Date(date)).getTime();
    const diffAbs = Math.abs(diff);
    for (const interval of intervals) {
        if (diffAbs >= interval.ge) {
            const x = Math.round(Math.abs(diff) / interval.divisor);
            const isFuture = diff < 0;
            return interval.unit ? rft.format(isFuture ? x : -x, interval.unit) : interval.text;
        }
    }
}

// examples
fromNow('2020-01-01') // 9 months ago
fromNow(161651684156) // 4 days ago
fromNow(new Date()-1) // just now
fromNow(30000 + Date.now()) // in 30 seconds
fromNow(Date.now() + (1000*60*60*24)) // in 1 day
fromNow(new Date('2029-12-01Z00:00:00.000')) // in 9 years

不使用 Intl.RelativeTimeFormat 的替代方案

/**
 * Human readable elapsed or remaining time (example: 3 minutes ago)
 * @param  {Date|Number|String} date A Date object, timestamp or string parsable with Date.parse()
 * @return {string} Human readable elapsed or remaining time
 * @author github.com/victornpb
 * @see https://stackoverflow.com/a/67338038/938822
 */
function fromNow(date) {
    const SECOND = 1000;
    const MINUTE = 60 * SECOND;
    const HOUR = 60 * MINUTE;
    const DAY = 24 * HOUR;
    const WEEK = 7 * DAY;
    const MONTH = 30 * DAY;
    const YEAR = 365 * DAY;
    const units = [
        { max: 30 * SECOND, divisor: 1, past1: 'just now', pastN: 'just now', future1: 'just now', futureN: 'just now' },
        { max: MINUTE, divisor: SECOND, past1: 'a second ago', pastN: '# seconds ago', future1: 'in a second', futureN: 'in # seconds' },
        { max: HOUR, divisor: MINUTE, past1: 'a minute ago', pastN: '# minutes ago', future1: 'in a minute', futureN: 'in # minutes' },
        { max: DAY, divisor: HOUR, past1: 'an hour ago', pastN: '# hours ago', future1: 'in an hour', futureN: 'in # hours' },
        { max: WEEK, divisor: DAY, past1: 'yesterday', pastN: '# days ago', future1: 'tomorrow', futureN: 'in # days' },
        { max: 4 * WEEK, divisor: WEEK, past1: 'last week', pastN: '# weeks ago', future1: 'in a week', futureN: 'in # weeks' },
        { max: YEAR, divisor: MONTH, past1: 'last month', pastN: '# months ago', future1: 'in a month', futureN: 'in # months' },
        { max: 100 * YEAR, divisor: YEAR, past1: 'last year', pastN: '# years ago', future1: 'in a year', futureN: 'in # years' },
        { max: 1000 * YEAR, divisor: 100 * YEAR, past1: 'last century', pastN: '# centuries ago', future1: 'in a century', futureN: 'in # centuries' },
        { max: Infinity, divisor: 1000 * YEAR, past1: 'last millennium', pastN: '# millennia ago', future1: 'in a millennium', futureN: 'in # millennia' },
    ];
    const diff = Date.now() - (typeof date === 'object' ? date : new Date(date)).getTime();
    const diffAbs = Math.abs(diff);
    for (const unit of units) {
        if (diffAbs < unit.max) {
            const isFuture = diff < 0;
            const x = Math.round(Math.abs(diff) / unit.divisor);
            if (x <= 1) return isFuture ? unit.future1 : unit.past1;
            return (isFuture ? unit.futureN : unit.pastN).replace('#', x);
        }
    }
};

于 2021-04-30T17:21:23.447 回答
11

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

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

于 2015-09-17T19:10:01.870 回答
8

从现在开始,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;
    }

}
于 2012-11-10T15:03:46.823 回答
7

这应该正确处理任何有效的时间戳,包括 Date.now()、单数单位和未来日期。我遗漏了几个月,但这些应该很容易添加。我尽量保持它的可读性。

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

于 2019-11-22T23:58:58.903 回答
6

另一种看法Intl.RelativeTimeFormat

  • 支持过去和未来的日期
  • 接受StringDate
  • 自定义范围很容易添加(编辑ranges
  • 可以很容易地翻译Intl.RelativeTimeFormat('ua')

console.log(timeAgo('2021-08-09T15:29:01+0000'));

function timeAgo(input) {
  const date = (input instanceof Date) ? input : new Date(input);
  const formatter = new Intl.RelativeTimeFormat('en');
  const ranges = {
    years: 3600 * 24 * 365,
    months: 3600 * 24 * 30,
    weeks: 3600 * 24 * 7,
    days: 3600 * 24,
    hours: 3600,
    minutes: 60,
    seconds: 1
  };
  const secondsElapsed = (date.getTime() - Date.now()) / 1000;
  for (let key in ranges) {
    if (ranges[key] < Math.abs(secondsElapsed)) {
      const delta = secondsElapsed / ranges[key];
      return formatter.format(Math.round(delta), key);
    }
  }
}

https://jsfiddle.net/tv9701uf

于 2021-09-09T18:04:29.220 回答
5

也可以使用 dayjs relativeTime插件来解决这个问题。

import * as dayjs from 'dayjs';
import * as relativeTime from 'dayjs/plugin/relativeTime';

dayjs.extend(relativeTime);
dayjs(dayjs('1990')).fromNow(); // x years ago
于 2019-07-02T18:35:14.773 回答
5

尽管这个问题是很久以前提出的,但写下这个答案希望它会对某人有所帮助。

通过您要开始计数的日期。momentjsmoment().fromNow()的使用:(在此处查看更多信息)

getRelativeTime(date) {
    const d = new Date(date * 1000);
    return moment(d).fromNow();
}

如果您想更改从现在开始的日期提供的信息,您可以写下您的自定义相对时间。

例如,在我自己的情况下,我想打印'one month ago'而不是'a month ago'由 moment(d).fromNow() 提供)。在这种情况下,您可以编写下面给出的内容。

moment.updateLocale('en', {
    relativeTime: {
        future: 'in %s',
        past: '%s ago',
        s: 'a few seconds',
        ss: '%d seconds',
        m: '1 m',
        mm: '%d minutes',
        h: '1 h',
        hh: '%d hours',
        d: '1 d',
        dd: '%d days',
        M: '1 month',
        MM: '%d months',
        y: '1 y',
        yy: '%d years'
    }
});

注意:我在Angular 6中为项目编写了代码

于 2018-09-10T10:52:32.900 回答
4

简单易读的版本:

const NOW = new Date()
const times = [["second", 1], ["minute", 60], ["hour", 3600], ["day", 86400], ["week", 604800], ["month", 2592000], ["year", 31536000]]

function timeAgo(date) {
    var diff = Math.round((NOW - date) / 1000)
    for (var t = 0; t < times.length; t++) {
        if (diff < times[t][1]) {
            if (t == 0) {
                return "Just now"
            } else {
                diff = Math.round(diff / times[t - 1][1])
                return diff + " " + times[t - 1][0] + (diff == 1?" ago":"s ago")
            }
        }
    }
}
于 2018-10-15T06:28:54.733 回答
3

我用 js 和 python 写了一个,在两个项目中使用,非常漂亮和简单:一个简单的库(小于 2kb),用于格式化日期和*** time ago语句。

简单、小巧、易于使用且经过良好测试。

  1. npm install timeago.js

  2. import timeago from 'timeago.js'; // or use script tag

  3. 使用 api format

样本:

var timeagoIns  = timeago();
timeagoIns .format('2016-06-12');

您也可以实时渲染。

var timeagoIns = timeago();
timeagoIns.render(document.querySelectorAll('time'));
于 2016-06-24T12:52:17.550 回答
3
function dateToHowManyAgo(stringDate){
    var currDate = new Date();
    var diffMs=currDate.getTime() - new Date(stringDate).getTime();
    var sec=diffMs/1000;
    if(sec<60)
        return parseInt(sec)+' second'+(parseInt(sec)>1?'s':'')+' ago';
    var min=sec/60;
    if(min<60)
        return parseInt(min)+' minute'+(parseInt(min)>1?'s':'')+' ago';
    var h=min/60;
    if(h<24)
        return parseInt(h)+' hour'+(parseInt(h)>1?'s':'')+' ago';
    var d=h/24;
    if(d<30)
        return parseInt(d)+' day'+(parseInt(d)>1?'s':'')+' ago';
    var m=d/30;
    if(m<12)
        return parseInt(m)+' month'+(parseInt(m)>1?'s':'')+' ago';
    var y=m/12;
    return parseInt(y)+' year'+(parseInt(y)>1?'s':'')+' ago';
}
console.log(dateToHowManyAgo('2019-11-07 19:17:06'));
于 2019-11-07T19:50:47.357 回答
2

我修改了 Sky Sanders 的版本。Math.floor(...) 操作在 if 块中进行评估

       var timeSince = function(date) {
            var seconds = Math.floor((new Date() - date) / 1000);
            var months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
            if (seconds < 5){
                return "just now";
            }else if (seconds < 60){
                return seconds + " seconds ago";
            }
            else if (seconds < 3600) {
                minutes = Math.floor(seconds/60)
                if(minutes > 1)
                    return minutes + " minutes ago";
                else
                    return "1 minute ago";
            }
            else if (seconds < 86400) {
                hours = Math.floor(seconds/3600)
                if(hours > 1)
                    return hours + " hours ago";
                else
                    return "1 hour ago";
            }
            //2 days and no more
            else if (seconds < 172800) {
                days = Math.floor(seconds/86400)
                if(days > 1)
                    return days + " days ago";
                else
                    return "1 day ago";
            }
            else{

                //return new Date(time).toLocaleDateString();
                return date.getDate().toString() + " " + months[date.getMonth()] + ", " + date.getFullYear();
            }
        }
于 2016-01-20T02:02:48.857 回答
2

回答10年前的问题以帮助新人。

我们可以将这个包用于那个javascript-time-ago

 
// Load locale-specific relative date/time formatting rules.
import en from 'javascript-time-ago/locale/en'
 
// Add locale-specific relative date/time formatting rules.
TimeAgo.addLocale(en)
 
// Create relative date/time formatter.
const timeAgo = new TimeAgo('en-US')
 
timeAgo.format(new Date())
// "just now"
 
timeAgo.format(Date.now() - 60 * 1000)
// "a minute ago"
 
timeAgo.format(Date.now() - 2 * 60 * 60 * 1000)
// "2 hours ago"
 
timeAgo.format(Date.now() - 24 * 60 * 60 * 1000)
// "a day ago"
于 2020-09-10T05:52:47.697 回答
2

我根据其他答案对此进行了尝试。

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;
}
于 2019-10-13T12:01:53.190 回答
2
const createdAt = moment(created_at).fromNow()

和定制的解决方案


        const duration = moment.duration(moment().diff(moment(created_at)))
        const createdAt = duration.as('week') >= 1
          ? `${Math.floor(duration.as('week'))} week(s)`
          : duration.as('day') >= 1
            ? `${Math.floor(duration.as('day'))} day(s)`
            : duration.as('hour') >= 1
              ? `${Math.floor(duration.as('hour'))} hour(s)`
              : `${Math.floor(duration.as('minute'))} minute(s)`

于 2021-11-18T07:12:21.480 回答
1
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";
}
于 2017-04-01T19:16:58.917 回答
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)')));
于 2018-06-03T12:26:11.840 回答
0
 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')));
于 2020-07-12T01:09:03.533 回答
0
function calDateAgo(dString=null){
    //var dString = "2021-04-1 12:00:00";
     
    var d1 = new Date(dString);
    var d2 = new Date();
    var t2 = d2.getTime();
    var t1 = d1.getTime();
    var d1Y = d1.getFullYear();
    var d2Y = d2.getFullYear();
    var d1M = d1.getMonth();
    var d2M = d2.getMonth();
     
    var time_obj = {};
    time_obj.year = d2.getFullYear()-d1.getFullYear();
    time_obj.month = (d2M+12*d2Y)-(d1M+12*d1Y);
    time_obj.week = parseInt((t2-t1)/(24*3600*1000*7));
    time_obj.day = parseInt((t2-t1)/(24*3600*1000));
    time_obj.hour = parseInt((t2-t1)/(3600*1000));
    time_obj.minute = parseInt((t2-t1)/(60*1000));
    time_obj.second = parseInt((t2-t1)/(1000));

    for (const obj_key in time_obj) {
        if(time_obj[obj_key] == 0){
            delete time_obj[obj_key];
        }
    }
    var ago_text = 'just now';

    if(typeof Object.keys(time_obj)[0] != 'undefined'){
        var time_key = Object.keys(time_obj)[0];
        var time_val = time_obj[Object.keys(time_obj)[0]];
        time_key += (time_val > 1) ? 's':'';
        ago_text = time_val+' '+time_key+' ago'; 
    }
    
    return ago_text;
}
于 2021-04-01T08:41:09.267 回答
0
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';
}
于 2021-10-28T12:06:58.627 回答
0

这是@sky-sanders 答案的简化版本。

function timeSince(date) {

  var seconds = Math.floor((new Date() - date) / 1000);
  var divisors = [31536000, 2592000, 86400, 3600, 60, 1]
  var description = ["years", "months", "days", "hours", "minutes", "seconds"]
  var result = [];

  var interval = seconds;

  for (i = 0; i < divisors.length; i++) {
    interval = Math.floor(seconds / divisors[i])
    if (interval > 1) {
      result.push(interval + " " + description[i])
    }
    seconds -= interval * divisors[i]
  }

  return result.join(" ")
}
于 2021-03-10T20:46:24.217 回答
0

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

因此,添加到解决方案中......如果您使用该react-intl库,他们有一个<FormattedRelative>组件。

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

于 2016-07-13T22:11:49.310 回答
0

这是我所做的(对象返回时间单位及其值):

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

于 2017-02-16T02:56:33.353 回答