以精确秒为单位的Javascript模糊时间(例如10分钟前的') [英] Javascript fuzzy time (e.g '10 minutes ago') that's in exact seconds

查看:54
本文介绍了以精确秒为单位的Javascript模糊时间(例如10分钟前的')的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在制作一个秒前"计数的JavaScript计数器.我的时间在JS时间对象中,在堆栈溢出的地方找到了时差"功能片段,但显示为"2小时前".如何显示"5小时10分钟37秒".

I'm making a javascript counter that counts 'seconds ago'. I have my time in a JS time object, and I found a "time difference" function snippet here on stack overflow, but it displays "2 hours ago". How can I get it to display "5 hours, 10 minutes and 37 seconds ago."

这就是我正在使用的东西:

Here's what I'm working with:

此函数将当前时间和某物的时间戳转换为"20秒前",而不是一个隐秘的日期:

This function converts the current time and the timestamp of something into "20 seconds ago" instead of a cryptic date:

function timeDifference(current, previous) {
    var msPerMinute = 60 * 1000;
    var msPerHour = msPerMinute * 60;
    var msPerDay = msPerHour * 24;
    var msPerMonth = msPerDay * 30;
    var msPerYear = msPerDay * 365;

    var elapsed = current - previous;

    if (elapsed < msPerMinute) {
         return Math.round(elapsed/1000) + ' seconds ago';   
    } else if (elapsed < msPerHour) {
         return Math.round(elapsed/msPerMinute) + ' minutes ago';   
    } else if (elapsed < msPerDay ) {
         return Math.round(elapsed/msPerHour ) + ' hours ago';   
    } else if (elapsed < msPerMonth) {
         return 'approximately ' + Math.round(elapsed/msPerDay) + ' days ago';   
    } else if (elapsed < msPerYear) {
         return 'approximately ' + Math.round(elapsed/msPerMonth) + ' months ago';   
    } else {
         return 'approximately ' + Math.round(elapsed/msPerYear ) + ' years ago';   
    }
}

这就是我用来每秒"计数的时间.我想说"5小时3分10秒前",然后再说1秒,"5小时3分11秒前"

And here's what I'm using to "count up" the time each second. I'd like it to say "5 hours, 3 minutes, 10 seconds ago" and then 1 second later, "5 hours, 3 minutes, 11 seconds ago"

var newTime = new Date(data.popular[i].timestamp*1000)
var relTime = timeDifference(new Date(),newTime)

setInterval(function(){
    var theTimeEl = $('.timestamp-large').filter(function(){
        return $(this).html() == relTime
    });
    newTime.setSeconds(newTime.getSeconds() + 1);
    var relTime = timeDifference(new Date(), newTime);
    $(theTimeEl).html(relTime);
    console.log(relTime)
}, 1000)

变量newTime是UTC javascript日期格式的时间.relTime是秒前"格式的时间.时间间隔遍历一堆时间戳元素,并为每个时间戳选择正确的一个.然后,它将时间增加一秒钟,将其转换回模糊时间"(几秒钟前),将html替换为新时间,并将其记录在控制台中.

The variable newTime is the time in the UTC javascript date format. relTime is that in "seconds ago" format. The interval loops through a bunch of timestamp elements and picks the right one for each time stamp. Then it adds a second to the time, converts it back into "fuzzy time" (seconds ago), replaces the html with the new time and logs it in the console.

如何将"5小时前"更改为"5小时37分钟,10秒之前"?时差功能需要修改.

推荐答案

这是一个与您所要求的功能接近的功能.

Here's a function that is close to what you're asking for.

var timeparts = [
   {name: 'year', div: 31536000000, mod: 10000},
   {name: 'day', div: 86400000, mod: 365},
   {name: 'hour', div: 3600000, mod: 24},
   {name: 'minute', div: 60000, mod: 60},
   {name: 'second', div: 1000, mod: 60}
];

function timeAgoNaive(comparisonDate) {
   var
      i = 0,
      l = timeparts.length,
      calc,
      values = [],
      interval = new Date().getTime() - comparisonDate.getTime();
   while (i < l) {
      calc = Math.floor(interval / timeparts[i].div) % timeparts[i].mod;
      if (calc) {
         values.push(calc + ' ' + timeparts[i].name + (calc != 1 ? 's' : ''));
      }
      i += 1;
   }
   if (values.length === 0) { values.push('0 seconds'); }
   return values.join(', ') + ' ago';
}

console.log(timeAgoNaive(new Date(Date.parse('Jun 12 2006 11:52:33'))));
console.log(timeAgoNaive(new Date(new Date().getTime() - 3600000)));
console.log(timeAgoNaive(new Date()));

结果:

6 years, 33 days, 4 hours, 52 minutes, 22 seconds ago
1 hour ago
0 seconds ago

我之所以称它为天真",是因为它并没有真正关注我们计算时间的人为方式.如果确切为"1/1/2013 12:01:00 am",则与"1/1/2012 12:01:00 am"相比,应得出"1年0个月0天0小时0分钟",0秒前".但是它不会通过扩展您所介绍的函数中的逻辑来做到这一点,也不会在我的函数中做到这一点(而且我的函数将不会使用数月).比365天更好的近似年数是365.24,但这也被忽略了.

I called it "naive" because it doesn't really pay attention to the human way that we calculate time. If it is "1/1/2013 12:01:00 am" exactly, comparing to "1/1/2012 12:01:00 am" should yield "1 year, 0 months, 0 days, 0 hours, 0 minutes, 0 seconds ago". But it won't do that by extending the logic in the function you presented, and it won't do that in my function either (plus my function won't use months). A better approximation of years than 365 days is 365.24, but that also is ignored.

我按照您的要求排除了空的时间部分,当找不到任何时间部分时,至少要保留"0秒".

I excluded the empty time parts as you requested, leaving "0 seconds" at a minimum when there are no time parts found.

现在,如果您想要那种类似于人的计算方式,则必须决定一些事情.您不能仅仅使用跨界的边界,因为2月28日到3月1日还不是一个月.其次,这里有一个问题将揭露真正的问题:

Now, if you want that human-like way of calculating, you have to decide some things. You can't just use boundaries crossed because Feb 28 to Mar 1 is not a whole month. Second, here's a question will expose the real problem:

  • 2月2日至3月31日是多少个月和几天?

如果您将2月2日到3月2日计算为一个月,则为1个月29天.但是,如果是1月2日到3月1日呢?他们之间经过的天数相同.现在是1个月(4月全天)+ 3月的1天+ 1月的31天(1个月32天)吗?您是否希望您的月份与实际日历一致,以便人类可以用手指回溯并从中获取正确的日期?那比你想的要难得多.

If you calculate Feb 2 to Mar 2 as one month, then it's 1 month 29 days. But what if it were Jan 2 to Mar 1? That's the same number of days elapsed between them. Is that now 1 month (for all of April) + 1 day in March + the 31 days in Jan for 1 month 32 days? Do you want your months to coincide to a physical calendar so a human could back track with his finger and get the correct date out of it? That is much harder than you think.

如果您能以明智而完整的规则回答有关如何进行类似人的时间计算"的事情,那么也许我可以为您编写另一个函数来做到这一点.

If you can answer with sensible and complete rules about how you would do "human-like elapsed time figuring" then maybe I can write you another function to do it.

更新

这是一个新功能,可以执行数月,并且一年中有365.24天(一个月中有30.43666666天):

Here's a new function that does months, and has 365.24 days in a year (30.43666666 days in a month):

var timeparts = [
   {name: 'millenni', div: 31556736000, p: 'a', s: 'um'},
   {name: 'centur', div: 3155673600, p: 'ies', s: 'y'},
   {name: 'decade', div: 315567360},
   {name: 'year', div: 31556736},
   {name: 'month', div: 2629728},
   {name: 'day', div: 86400},
   {name: 'hour', div: 3600},
   {name: 'minute', div: 60},
   {name: 'second', div: 1}
];

function timeAgoNaive2(comparisonDate) {
   var i = 0,
      parts = [],
      interval = Math.floor((new Date().getTime() - comparisonDate.getTime()) / 1000);
   for ( ; interval > 0; i += 1) {
      var value = Math.floor(interval / timeparts[i].div);
      interval = interval - (value * timeparts[i].div);
      if (value) {
         parts.push(value + ' ' + timeparts[i].name + (value !== 1 ? timeparts[i].p || 's' : timeparts[i].s || ''));
      }
   }
   if (parts.length === 0) { return 'now'; }
   return parts.join(', ') + ' ago';
}

console.log(timeAgoNaive2(new Date(Date.parse('Jun 12 2006 11:52:33'))));
console.log(timeAgoNaive2(new Date(new Date().getTime() - 3600000)));
console.log(timeAgoNaive2(new Date()));
console.log(timeAgoNaive2(new Date(-92709631247000)));

输出:

6 years, 1 month, 1 day, 10 hours, 53 minutes, 44 seconds ago
1 hour ago
now
2 millennia, 9 centuries, 8 decades, 4 months, 26 days, 22 hours, 41 minutes, 47 seconds ago

它仍然很幼稚,但是做得更好.另外,它将适用于像B.C.这样的真正古老的日期.那些.:)

It is still naive, but it does a little better job. Plus it will work for REALLY old dates like B.C. ones. :)

这篇关于以精确秒为单位的Javascript模糊时间(例如10分钟前的&amp;#39;)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆