Javascript模糊时间(例如’10分钟前’)就是精确的秒数

我正在制作一个计算’秒前’的javascript计数器。 我有时间在JS时间对象中,我在堆栈溢出时发现了一个“时差”function片段,但它显示“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) + ' 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秒前”

 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秒前”? 需要修改时差函数。

这是一个接近你所要求的function。

 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,但这也被忽略了。

我按你的要求排除了空的时间部分,当没有找到时间部分时,至少留下“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天1个月32天? 您是否希望您的月份与实际日历重合,以便人类可以用他的手指回溯并从中获取正确的日期? 这比你想象的要困难得多。

如果你可以用合理而完整的规则来回答你将如何做“像人类一样的经过时间的计算”,那么也许我可以为你写另一个function来做到这一点。

更新

这是一个几个月的新function,一年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); 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))); 

输出:

 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 

它仍然很幼稚,但它做得更好。 此外,它将适用于像BC一样的旧日期。 🙂

改变逻辑,以便不仅可以找到单个最大的测量单位,而是对剩余部分做一些事情。

基本上你需要做的是从最大的增量开始,找到值,然后从总数中减去它以得到余数。 然后重复一遍

这样的事可能,我还没有测试过。

 var elapsed = current - previous; var remainder = elapsed; int years; int months; years = Math.floor(remainder/msPerYear); remainder = remainder % msPerYear; months = Math.floor(remainder/msPerMonth); remainder = remainder % msPerMonth; // repeat 

然后只需从变量中构建字符串。

这应该是诀窍:

 var msPerMinute = 60 * 1000; var msPerHour = msPerMinute * 60; var msPerDay = msPerHour * 24; var msPerMonth = msPerDay * 30; var msPerYear = msPerDay * 365; function timeDifference(current, previous) { var remainder = current - previous; var message = ""; var sep = ""; var years = Math.floor(remainder/msPerYear); remainder = remainder - years * msPerYear; if (years > 0) { message += years + " years"; sep = ", "; console.log(message); } var months = Math.floor(remainder/msPerMonth); remainder = remainder - months * msPerMonth; if (months > 0) { message += sep + months + " months"; sep = ", "; console.log(message); } var days = Math.floor(remainder/msPerDay); remainder = remainder - days * msPerDay; if (days > 0) { message += sep + days + " days"; sep = ", "; console.log(message); } var hours = Math.floor(remainder/msPerHour); remainder = remainder - hours * msPerHour; if (hours > 0) { message += sep + hours + " hours"; sep = ", "; console.log(message); } var minutes = Math.floor(remainder/msPerMinute); remainder = remainder - minutes * msPerMinute; if (months > 0) { message += sep + minutes + " minutes"; sep = ", "; console.log(message); } var seconds = Math.floor(remainder/1000); remainder = remainder - seconds * 1000; if (months > 0) { message += sep + seconds + " seconds"; sep = ", "; console.log(message); } message += " ago"; var pos = message.lastIndexOf(','); message = message.substring(0,pos) + ' and' + message.substring(pos+1) return message; }; var output = timeDifference(new Date(2012, 10, 20, 12, 0, 59), new Date(2012, 2, 13, 10, 15, 12)); console.log(output); 

输出:8个月,12天,1小时,45分钟和47秒前

这当然可以重构为重复性稍差。 你可以试试这个小提琴: http : //jsfiddle.net/vawEf/