代码之家  ›  专栏  ›  技术社区  ›  Nick Sergeant

如何在JavaScript中呈现两个时间戳之间的上下文差异?

  •  5
  • Nick Sergeant  · 技术社区  · 17 年前

    假设我有两个JavaScript字符串:

    var date1 = '2008-10-03T20:24Z'
    var date2 = '2008-10-04T12:24Z'
    

    我怎么会得出这样的结果:

    '4 weeks ago'
    

    或

    'in about 15 minutes'
    

    过去的差异有解决方案,但我还没有找到一个支持未来时间差异的解决方案。

    以下是我尝试过的解决方案:

    John Resig's Pretty Date 和 Zach Leatherman's modification

    jQuery解决方案的额外积分。

    2 回复  |  直到 17 年前
        1
  •  7
  •   moonshadow    17 年前

    查看您链接的解决方案。。。这其实和我的无聊评论一样简单!

    这里有一个版本的Zach Leatherman代码,为您的未来日期预先添加了“In”。如您所见,这些变化非常小。

      function humane_date(date_str){
          var time_formats = [
              [60, 'Just Now'],
              [90, '1 Minute'], // 60*1.5
              [3600, 'Minutes', 60], // 60*60, 60
              [5400, '1 Hour'], // 60*60*1.5
              [86400, 'Hours', 3600], // 60*60*24, 60*60
              [129600, '1 Day'], // 60*60*24*1.5
              [604800, 'Days', 86400], // 60*60*24*7, 60*60*24
              [907200, '1 Week'], // 60*60*24*7*1.5
              [2628000, 'Weeks', 604800], // 60*60*24*(365/12), 60*60*24*7
              [3942000, '1 Month'], // 60*60*24*(365/12)*1.5
              [31536000, 'Months', 2628000], // 60*60*24*365, 60*60*24*(365/12)
              [47304000, '1 Year'], // 60*60*24*365*1.5
              [3153600000, 'Years', 31536000], // 60*60*24*365*100, 60*60*24*365
              [4730400000, '1 Century'], // 60*60*24*365*100*1.5
          ];
    
          var time = ('' + date_str).replace(/-/g,"/").replace(/[TZ]/g," "),
              dt = new Date,
              seconds = ((dt - new Date(time) + (dt.getTimezoneOffset() * 60000)) / 1000),
              token = ' Ago',
              prepend = '',
              i = 0,
              format;
    
          if (seconds < 0) {
              seconds = Math.abs(seconds);
              token = '';
              prepend = 'In ';
          }
    
          while (format = time_formats[i++]) {
              if (seconds < format[0]) {
                  if (format.length == 2) {
                      return (i>1?prepend:'') + format[1] + (i > 1 ? token : ''); // Conditional so we don't return Just Now Ago
                  } else {
                      return prepend + Math.round(seconds / format[2]) + ' ' + format[1] + (i > 1 ? token : '');
                  }
              }
          }
    
          // overflow for centuries
          if(seconds > 4730400000)
              return Math.round(seconds / 4730400000) + ' Centuries' + token;
    
          return date_str;
      };
    
        2
  •  3
  •   nickf    17 年前

    呵呵,我昨天确实写了一个函数来完成这件事(它不在这台计算机上,所以我只能试着记住它)

    Date.prototype.toRelativeTime = function(otherTime) {
        // if no parameter is passed, use the current date.
        if (otherTime == undefined) otherTime = new Date();
    
        var diff = Math.abs(this.getTime() - otherTime.getTime()) / 1000;
    
        var MIN = 60,        // some "constants" just 
            HOUR = 3600,     // for legibility
            DAY = 86400
        ;
        var out, temp;
        if (diff < MIN) {
            out = "Less than a minute";
    
        } else if (diff < 15 * MIN) {
            // less than fifteen minutes, show how many minutes
            temp = Math.round(diff / MIN);
            out = temp + " minute" + (temp == 1 ? "" : "s");
            // eg: 12 minutes
        } else if (diff < HOUR) {
            // less than an hour, round down to the nearest 5 minutes
            out = (Math.floor(diff / (5 * MIN)) * 5) + " minutes";
        } else if (diff < DAY) {
            // less than a day, just show hours
            temp = Math.round(diff / HOUR);
            out = temp + " hour" + (temp == 1 ? "" : "s");
        } else if (diff < 30 * DAY) {
            // show how many days ago
            temp = Math.round(diff / DAY);
            out = temp + " day" + (temp == 1 ? "" : "s");
        } else if (diff < 90 * DAY) {
            // more than 30 days, but less than 3 months, show the day and month
            return this.getDate() + " " + this.getShortMonth();  // see below
        } else {
            // more than three months difference, better show the year too
            return this.getDate() + " " + this.getShortMonth() + " " + this.getFullYear();
        }
        return out + (this.getTime() > otherTime.getTime() ? " from now" : " ago");
    
    };
    
    Date.prototype.getShortMonth = function() {
        return ["Jan", "Feb", "Mar",
                "Apr", "May", "Jun",
                "Jul", "Aug", "Sep",
                "Oct", "Nov", "Dec"][this.getMonth()];
    };
    
    // sample usage:
    var x = new Date(2008, 9, 4, 17, 0, 0);
    alert(x.toRelativeTime());    // 9 minutes from now
    
    x = new Date(2008, 9, 4, 16, 45, 0, 0);
    alert(x.toRelativeTime());    // 6 minutes ago
    
    x = new Date(2008, 11, 1);    // 1 Dec
    
    x = new Date(2009, 11, 1);    // 1 Dec 2009