草庐IT

精确到秒的 Javascript 模糊时间(例如 '10 minutes ago')

coder 2024-07-15 原文

我正在制作一个计算“秒前”的 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) + ' 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 是“秒前”格式。 interval 循环遍历一堆时间戳元素,并为每个时间戳选择正确的一个。然后它在时间上加一秒,将其转换回“模糊时间”(秒前),用新时间替换 html 并将其记录在控制台中。

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

最佳答案

这是一个接近您要求的功能。

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 天?您是否希望您的月份与物理日历一致,以便人们可以用他的手指回溯并从中获取正确的日期?这比您想象的要难得多。

如果你能用明智而完整的规则回答你将如何进行“类似人类的耗时计算”,那么也许我可以为你编写另一个函数来完成它。

更新

这是一个执行月份的新函数,一年有 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) {
      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. 这样的真正古老的日期。那些。 :)

关于精确到秒的 Javascript 模糊时间(例如 '10 minutes ago'),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11479170/

有关精确到秒的 Javascript 模糊时间(例如 '10 minutes ago')的更多相关文章

  1. ruby-on-rails - rails : "missing partial" when calling 'render' in RSpec test - 2

    我正在尝试测试是否存在表单。我是Rails新手。我的new.html.erb_spec.rb文件的内容是:require'spec_helper'describe"messages/new.html.erb"doit"shouldrendertheform"dorender'/messages/new.html.erb'reponse.shouldhave_form_putting_to(@message)with_submit_buttonendendView本身,new.html.erb,有代码:当我运行rspec时,它失败了:1)messages/new.html.erbshou

  2. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  3. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  4. ruby-on-rails - Rails 3.2.1 中 ActionMailer 中的未定义方法 'default_content_type=' - 2

    我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer

  5. ruby - 在 jRuby 中使用 'fork' 生成进程的替代方案? - 2

    在MRIRuby中我可以这样做:deftransferinternal_server=self.init_serverpid=forkdointernal_server.runend#Maketheserverprocessrunindependently.Process.detach(pid)internal_client=self.init_client#Dootherstuffwithconnectingtointernal_server...internal_client.post('somedata')ensure#KillserverProcess.kill('KILL',

  6. ruby - 主要 :Object when running build from sublime 的未定义方法 `require_relative' - 2

    我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby​​1.9+ 关于ruby-主要:Objectwhenrun

  7. ruby - 无法让 RSpec 工作—— 'require' : cannot load such file - 2

    我花了三天的时间用头撞墙,试图弄清楚为什么简单的“rake”不能通过我的规范文件。如果您遇到这种情况:任何文件夹路径中都不要有空格!。严重地。事实上,从现在开始,您命名的任何内容都没有空格。这是我的控制台输出:(在/Users/*****/Desktop/LearningRuby/learn_ruby)$rake/Users/*******/Desktop/LearningRuby/learn_ruby/00_hello/hello_spec.rb:116:in`require':cannotloadsuchfile--hello(LoadError) 最佳

  8. ruby-on-rails - 新 Rails 项目 : 'bundle install' can't install rails in gemfile - 2

    我已经像这样安装了一个新的Rails项目:$railsnewsite它执行并到达:bundleinstall但是当它似乎尝试安装依赖项时我得到了这个错误Gem::Ext::BuildError:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcheckingforlibkern/OSAtomic.h...yescreatingMakefilemake"DESTDIR="cleanmake"DESTDIR="

  9. ruby-on-rails - rspec should have_select ('cars' , :options => ['volvo' , 'saab' ] 不工作 - 2

    关闭。这个问题需要detailsorclarity.它目前不接受答案。想改进这个问题吗?通过editingthispost添加细节并澄清问题.关闭8年前。Improvethisquestion在首页我有:汽车:VolvoSaabMercedesAudistatic_pages_spec.rb中的测试代码:it"shouldhavetherightselect"dovisithome_pathit{shouldhave_select('cars',:options=>['volvo','saab','mercedes','audi'])}end响应是rspec./spec/request

  10. ruby-on-rails - Rails 中的 NoMethodError::MailersController#preview undefined method `activation_token=' for nil:NilClass - 2

    似乎无法为此找到有效的答案。我正在阅读Rails教程的第10章第10.1.2节,但似乎无法使邮件程序预览正常工作。我发现处理错误的所有答案都与教程的不同部分相关,我假设我犯的错误正盯着我的脸。我已经完成并将教程中的代码复制/粘贴到相关文件中,但到目前为止,我还看不出我输入的内容与教程中的内容有什么区别。到目前为止,建议是在函数定义中添加或删除参数user,但这并没有解决问题。触发错误的url是http://localhost:3000/rails/mailers/user_mailer/account_activation.http://localhost:3000/rails/mai

随机推荐