Javascript模糊时间(例如“10分钟前”),正好在几秒钟内 [英] Javascript fuzzy time (e.g '10 minutes ago') that's in exact seconds

查看:94
本文介绍了Javascript模糊时间(例如“10分钟前”),正好在几秒钟内的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在制作一个数秒钟前的JavaScript计数器。我有时间在JS时间对象中,我在堆栈溢出中发现了一个时差功能片段,但它显示2小时前。如何让它显示5小时10分37秒。



这是我正在使用的:



此函数将当前时间和时间戳转换为20秒前而不是隐藏日期:

  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)+'分钟前';
} else if(elapsed< msPerDay){
return Math.round(elapsed / msPerHour)+'hours ago';
} else if(elapsed< msPerMonth){
return'approx'+ Math.round(elapsed / msPerDay)+'days ago';
} else if(elapsed< msPerYear){
return'approx'+ Math.round(elapsed / msPerMonth)+'months ago';
} else {
return'approx'+ Math.round(elapsed / msPerYear)+'years ago';
}
}

这里是我用来 每秒钟的时间。我想要说5小时,3分10秒,然后1秒钟后,5小时,3分11秒

  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并将其记录在控制台中。



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

解决方案

这是一个接近你所要求的功能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年,33天,4小时,52分钟,22秒前
1小时前
0秒前

我称之为天真的,因为它并没有真正关注我们计算时间的人性化方式。如果是1/1/2013 12:01:00 am,比较1/1/2012 12:01:00 am应该产生1年0个月0天0小时0分,0秒前。但是它不会通过扩展你所呈现的函数中的逻辑来实现,也不会在我的函数中执行(加上我的函数不会使用几个月)。多于365天的更好的近似值为365.24,但也被忽略。



我按照您的要求排除了空的时间部分,最少留下0秒当没有找到时间部分。



现在,如果你想要像人类一样的计算方式,你必须决定一些事情。你不能只是使用边界,因为2月28日到3月1日不是整个月。第二,这个问题会揭露真正的问题:




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



如果您计算2月2日至3月2日为一个月,则为1个月29天。但如果是1月2日到3月1日呢?这是他们之间经过的相同的天数。现在是1个月(4月份)+ 3月1日+ 1月31日31天32天?你想让你的几个月与物理日历相吻合,人类可以用他的手指回溯,并得到正确的日期吗?这比你想象的要困难得多。



如果你可以用明智而完整的规则回答你如何像人类一样的经过时间,那么也许我可以写你还有另一个功能。



更新



这是一个新功能几个月,一年365.24天(一个月30.43666666天):

  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); (; interval> 0; i + = 1)
{
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)));

输出:

 code> 6年,1个月,1天,10小时,53分钟,44秒前
1小时前
现在
2千年,9个世纪,8年,4个月,26天,22小时,41分钟,47秒前

它还是天真的,但它一点点更好的工作此外,它将适用于非常旧的日期,如B.C.那些。 :)


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:

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

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)

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.

How do I change "5 hours ago" to "5 hours, 37 mintues, 10 seconds ago"? The time difference function needs to be modified.

解决方案

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

Results:

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

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.

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

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:

  • How many months and days is Feb 2 to Mar 31?

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.

Update

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

Output:

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

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分钟前”),正好在几秒钟内的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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