【问题标题】:Calculate time elapsed using javascript使用javascript计算经过的时间
【发布时间】:2012-04-09 06:53:21
【问题描述】:

我想使用 JavaScript 以(年、月、日、小时、分钟、秒)的形式计算自生日以来经过的时间。

例如,我的出生日期是 1989 年 10 月 15 日,00 时 00 分 00 秒。因此,从我的出生日期开始经过的时间是,

22 years 5 months 10 days 19 hours 25 minutes 25 seconds 

我想使用 JavaScript 代码实现相同的输出。在这种情况下,任何链接左右肯定会有所帮助。

【问题讨论】:

  • 您需要两个javascript Date 对象:一个代表当前日期,一个代表您的出生日期。然后,您需要编写代码通过比较两个对象来构建该字符串。
  • 是的,我已经实现了可以计算小时、分钟和秒的部分。猜猜这是比较容易的部分,因为我正在努力计算天数和月份。

标签: javascript


【解决方案1】:

试试这样的:

var now = new Date();
var bDay = new Date(1989, 10, 15);
var elapsedT = now - bDay; // in ms

阅读MDN 了解更多信息。这会让你知道如何格式化结果。

【讨论】:

  • 忘了提...如果您不喜欢处理 JS Date API,请查看momentjs.com。该库包含一些合理的默认操作。
  • 这对我不起作用。我需要 var elapsedT = now - bDay 而不是
  • @nishantjr 谢谢,调整了。
【解决方案2】:

由于我之前的回答让人们完全忽略了这一点,这里有一个 PHP 代码端口,我必须做同样的事情:

function getDaysInMonth(month,year) {     
    if( typeof year == "undefined") year = 1999; // any non-leap-year works as default     
    var currmon = new Date(year,month),     
        nextmon = new Date(year,month+1);
    return Math.floor((nextmon.getTime()-currmon.getTime())/(24*3600*1000));
} 
function getDateTimeSince(target) { // target should be a Date object
    var now = new Date(), diff, yd, md, dd, hd, nd, sd, out = [];
    diff = Math.floor(now.getTime()-target.getTime()/1000);
    yd = target.getFullYear()-now.getFullYear();
    md = target.getMonth()-now.getMonth();
    dd = target.getDate()-now.getDate();
    hd = target.getHours()-now.getHours();
    nd = target.getMinutes()-now.getMinutes();
    sd = target.getSeconds()-now.getSeconds();
    if( md < 0) {yd--; md += 12;}
    if( dd < 0) {
        md--;
        dd += getDaysInMonth(now.getMonth()-1,now.getFullYear());
    }
    if( hd < 0) {dd--; hd += 24;}
    if( md < 0) {hd--; md += 60;}
    if( sd < 0) {md--; sd += 60;}

    if( yd > 0) out.push( yd+" year"+(yd == 1 ? "" : "s"));
    if( md > 0) out.push( md+" month"+(md == 1 ? "" : "s"));
    if( dd > 0) out.push( dd+" day"+(dd == 1 ? "" : "s"));
    if( hd > 0) out.push( hd+" hour"+(hd == 1 ? "" : "s"));
    if( nd > 0) out.push( nd+" minute"+(nd == 1 ? "" : "s"));
    if( sd > 0) out.push( sd+" second"+(sd == 1 ? "" : "s"));
    return out.join(" ");
}

例子:

getDateTimeSince(new Date(1992,1,6,22,30,00)); 
// my date of birth - near enough half past ten in the evening on Feb 6th 1992
> 20 years 1 month 18 days 17 hours 23 minutes 7 seconds

我相信这正是 OP 所要求的。

【讨论】:

  • 感谢这段代码。这是一个好的开始。对于其他可能使用它的人,我不得不颠倒减法的顺序。此外,除非我的逻辑存在深夜缺陷,否则我认为条件进位操作的顺序也应该颠倒(首先是最不重要的时间跨度)。最后,根本没有使用 diff .. 不知道为什么会这样。无论如何,伟大的贡献!
【解决方案3】:

首先,您的要求有点不精确。我们知道一分钟 = 60 秒,一小时 = 60 分钟……它停在这里。一天可以是 24 小时,也可以是略多于 24 小时,这取决于您如何对待闰年,而“一个月”甚至不会试图准确地表示时间跨度。

因此:要么将时间跨度保持为小时,要么建立一个近似值来处理闰年等。日期和日期差异(时间跨度)是不同的概念,需要始终区别对待。 p>

无论如何,至于代码,我只是去:

var ms = new Date() - yourBirthDate;
var secs = ms/1000;

var minutes = secs    / 60 ;  secs    = secs    % 60;
var hours   = minutes / 60 ;  minutes = minutes % 60;
// and so on if you want

【讨论】:

  • 你是对的!!但我相信这就是挑战!
  • 挑战在于以一种可以回答的方式表述您的问题。 :)“多长时间问题”的精确答案(如果您追求精确度)只能用 SI 时间单位表示,或者它们的倍数,如小时或天(但不是太阳日)。如果您在几个月后,您只能说从那时起已经开始了多少个月。当我说我 23 岁时,我只是说我已经过很多次生日,而不是确切的时间跨度。
【解决方案4】:

使用 Moment.js 在 Javascript 中解析、验证、操作和格式化日期。只有 5.5k,所以现在没有太多理由自己编写这种低级代码。

http://momentjs.com/

【讨论】:

    【解决方案5】:

    看看JavaScript Date object。具体来说,在该页面上,查找“计算经过时间”部分(靠近底部):

    // using static methods
    var start = Date.now();
    // the event you'd like to time goes here:
    doSomethingForALongTime();
    var end = Date.now();
    var elapsed = end - start; // time in milliseconds
    

    在您的情况下,start 将是给定日期:

    var start = new Date(1989,10,15);
    

    【讨论】:

      【解决方案6】:

      如果您想计算天数,甚至是周数,只需从您的生日时间戳中减去当前时间戳,然后将该数字除为其组成时间单位即可。

      但是,如果您想要几个月和几年,由于一个月中的天数可变,它会稍微复杂一些。

      也许最简单的方法如下:

      1. 获取年份差异(currentYear -birthYear)
      2. 获取月差(currentMonth -birthMonth)
      3. 对所有单位重复
      4. 如果任何单位为负数,则从上面的单位中减去 1,然后加上当前单位中的许多组成更大的单位。

      当您想找出给定月份中有多少天时,就会出现复杂情况。这会有所帮助:

      function getDaysInMonth(month,year) {
          if( typeof year == "undefined") year = 1999; // any non-leap-year works as default
          var currmon = new Date(year,month),
              nextmon = new Date(year,month+1); // no need to check for December overflow - JS does this automatically
          return Math.floor((nextmon.getTime()-currmon.getTime())/24*3600);
      }
      

      这应该足以让您走上正轨。如果您需要更多帮助,请告诉我。

      【讨论】:

      • 我认为这有点误导。没有“月差”之类的东西。一个月不是时间跨度。
      • 我今年 20 岁零一个月。在这种情况下,一个月怎么不是时间跨度,这是 OP 所询问的上下文? “我想计算自生日以来经过的时间……”
      • 如果今天是 3 月 25 日,那么 1 个月前是哪一天?是 31 天还是 29 天前?我不知道。
      • 显然是 29 天,因为“1 个月前”是 2 月 25 日。不过,从 3 月 31 日开始询问一个月前是什么有点复杂,但是当算法达到这个程度时,日期本身就有些抽象了。
      • 3 月 31 日的示例表明,无论您选择什么规则,最终都会遇到不一致和边缘情况,因为一个月可能意味着不是固定的时间跨度。
      【解决方案7】:
      function getDaysInMonth(month,year) {     
          if( typeof year == "undefined") year = 1999; // any non-leap-year works as default     
          var currmon = new Date(year,month),     
              nextmon = new Date(year,month+1);
          return Math.floor((nextmon.getTime()-currmon.getTime())/(24*3600*1000));
      } 
      function getDateTimeSince(target) { // target should be a Date object
          var now = new Date(), yd, md, dd, hd, nd, sd, out = []; 
      
          yd = now.getFullYear()-target.getFullYear();
          md = now.getMonth()-target.getMonth();
          dd = now.getDate()-target.getDate();
          hd = now.getHours()-target.getHours();
          nd = now.getMinutes()-target.getMinutes();
          sd = now.getSeconds()-target.getSeconds(); 
      
          if( md < 0) {yd--; md += 12;}
          if( dd < 0) {
              md--;
              dd += getDaysInMonth(now.getMonth()-1,now.getFullYear());
          }
          if( hd < 0) {dd--; hd += 24;}
          if( nd < 0) {hd--; nd += 60;}
          if( sd < 0) {nd--; sd += 60;}
      
          if( yd > 0) out.push( yd+" year"+(yd == 1 ? "" : "s"));
          if( md > 0) out.push( md+" month"+(md == 1 ? "" : "s"));
          if( dd > 0) out.push( dd+" day"+(dd == 1 ? "" : "s"));
          if( hd > 0) out.push( hd+" hour"+(hd == 1 ? "" : "s"));
          if( nd > 0) out.push( nd+" minute"+(nd == 1 ? "" : "s"));
          if( sd > 0) out.push( sd+" second"+(sd == 1 ? "" : "s"));
          return out.join(" ");
      }
      

      这是 Kolink 代码的不同版本。他的一些错误导致这个脚本无法正常工作......

      【讨论】:

      • 警告:此代码继续被破坏 - 它不处理秒计算的分钟边界,以及分钟计算的小时边界等等。例如,假设现在是 11:31:05(上午 11:31 和 5 秒),我们用 11:30:55 调用它,它会说经过的时间是 1 分 10 秒,而实际上这两个时间戳之间的差异是:10 秒。
      • 为了我的目的(查找自昨天以来已经过去了多少天和多少小时)它工作得很好。
      【解决方案8】:

      这是计算经过时间的简单方法。

      1. 以毫秒为单位计算起始日期和今天之间的差异
      2. 将此差异传递给名为 result 的 Date 对象
      3. 请记住,从日期对象定义中,该结果对象是从 01/01/1970 00:00:00 开始的毫秒数。
      4. 检查此结果对象以获取年、月等。

      这是执行此操作的代码。

      Date.prototype.getElapsedTime = function() {
        var diffDate = new Date(Date.now() - this);
        return "Elapsed Time: Years: " + (diffDate.getFullYear() - 1970) + ", Months: " + diffDate.getMonth() + ", Days: " + (diffDate.getDate() - 1) + ", Hours: " + diffDate.getHours() + ", Minutes: " + diffDate.getMinutes() + ", Seconds: " + diffDate.getSeconds();
      };
      
      var from = new Date("01/08/1986 04:07:00");
      document.getElementById("result").innerHTML = from.getElapsedTime();
      

      这里有一些你可以玩的东西:https://jsfiddle.net/nishchal/u8gt2gwq/4/

      【讨论】:

        【解决方案9】:

        我喜欢这个:

        function lifeSpan(t0) {var x=new Date()-t0, a=x, i=0,s=0,m=0,h=0,j=0;
          if(a>=1){i=a%1000;a=(a-i)/1000;
          if(a>=1){s=a%60;a=(a-s)/60;
          if(a>=1){m=a%60;a=(a-m)/60;
          if(a>=1){h=a%24;a=(a-h)/24;
          if(a>=1){j=a;//...
          }}}}}
          return 'Elapsed: '+i+'ms '+s+'s '+m+'mn '+h+'h '+j+'j (or '+x+'ms).';}
        

        【讨论】:

          【解决方案10】:

          这是一个快速算法,用于显示自 unix/epoch 时间戳以来经过的时间:

          const showElapsedTime = (timestamp) => {
              if (typeof timestamp !== 'number') return 'NaN'        
          
              const SECOND = 1000
              const MINUTE = 1000 * 60
              const HOUR = 1000 * 60 * 60
              const DAY = 1000 * 60 * 60 * 24
              const MONTH = 1000 * 60 * 60 * 24 * 30
              const YEAR = 1000 * 60 * 60 * 24 * 30 * 12
              
              const elapsed = ((new Date()).valueOf() - timestamp)
              
              if (elapsed <= MINUTE) return `${Math.round(elapsed / SECOND)}s`
              if (elapsed <= HOUR) return `${Math.round(elapsed / MINUTE)}m`
              if (elapsed <= DAY) return `${Math.round(elapsed / HOUR)}h`
              if (elapsed <= MONTH) return `${Math.round(elapsed / DAY)}d`
              if (elapsed <= YEAR) return `${Math.round(elapsed / MONTH)}mo`
              return `${Math.round(elapsed / YEAR)}y`
          }
                
          const createdAt = 1541301301000
          
          console.log(showElapsedTime(createdAt + 5000000))
          console.log(showElapsedTime(createdAt))
          console.log(showElapsedTime(createdAt - 500000000))

          (new Date()).valueOf() 返回自 1970 年 1 月 1 日以来经过的秒数。

          得到它之后,您只需要事件的时间戳,您可以从当前时间中减去它。这留下了经过的秒数,可以通过除以正确的单位数将其转换为人类可读的格式。

          例如,3000 毫秒就是 300 秒。我展示的算法适用于毫秒时间戳(将所有内容除以 1000 秒),因此在算法中,3000 将大于MINUTE 但小于HOUR,因此它将返回3000 / MINUTE 并返回3s .

          如果您要显示卡片,例如发布在2d ago 的职位发布,此算法很有用。

          我不喜欢我找到的大多数其他答案,因为它们不够简单或不够可读。我希望我的回答很快就能被理解。

          【讨论】:

            【解决方案11】:

            这里是查找经过时间的简单算法:

              time_elapsed_string = function(ptime){
                var etime = (Date.now() / 1000 | 0 ) - ptime;
            
                if (etime < 1)
                {
                  return '0 seconds';
                }
            
                var a = {'31536000' :  'year',
                          '2592000'  :  'month',
                          '86400' :  'day',
                          '3600' :  'hour',
                          '60'  :  'minute',
                          '1'  :  'second'
                        };
                var a_plural = { 'year'   : 'years',
                                  'month'  : 'months',
                                  'day'    : 'days',
                                  'hour'   : 'hours',
                                  'minute' : 'minutes',
                                  'second' : 'seconds'
                                };
                var output = '';
                $.each(a,function(secs,str){
                    var d = etime / secs;
                    if (d >= 1){
                      var r = Math.round(d);
                      output = r + ' ' + (r > 1 ? a_plural[str] : str) + ' ago';
                      return true;
                    }
                });
                return output;
              }

            【讨论】:

              【解决方案12】:

              我想出了以下内容:

              let getTimeElpasedString = (datetime, depth=1 )=>{
                  /*
                      depth = 0 means start at milliseconds
                      depth = 1 means start at seconds
                      ...
                  */
                  datetime = Date.parse(datetime).getElapsed()
                  console.log(datetime)
                  let dividers = [1000, 60, 60, 24, 7]
                  let str = ''
                  let units = ["milliseconds", "seconds", "minutes", "hours", "days"]
                  let reminders = []
                  dividers.forEach(d=>{
                      reminders.push(datetime % d)
                      datetime = parseInt(datetime/d) 
                  })
                  reminders = reminders.slice(depth).reverse()
                  units = units.slice(depth).reverse()
                  for(let i=0; i<reminders.length; i++){
                      // skip which is equal to zero
                      if(reminders[i] != 0)
                          str += `${reminders[i]} ${units[i]} `
                  }
                  return str + "ago"
              }
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2016-04-25
                • 2020-12-01
                • 1970-01-01
                相关资源
                最近更新 更多