Как отобразить контекстную разницу между двумя временными метками в JavaScript? - PullRequest
5 голосов
/ 04 октября 2008

Допустим, у меня есть две строки в JavaScript:

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

Как бы я пришел к такому результату:

'4 weeks ago'

или

'in about 15 minutes'

(должен поддерживать прошлое и будущее).

Существуют решения для прошлых различий, но я еще не нашел решение с поддержкой будущих различий.

Вот решения, которые я попробовал:

Прекрасное свидание Джона Резига и модификация Зака ​​Лезермана

Бонусные баллы за решение jQuery.

Ответы [ 2 ]

7 голосов
/ 04 октября 2008

Глядя на решения, которые вы связали ... это на самом деле так же просто, как мой легкомысленный комментарий!

Вот версия кода Зак Кожаного человека, которая добавляет «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;
  };
3 голосов
/ 04 октября 2008

Хех - на самом деле я вчера написал функцию, которая делает именно эту вещь (и ее нет на этом компьютере, поэтому мне просто нужно попытаться ее запомнить)

Я расширил класс-прототип Date, но это довольно легко можно просто поместить в обычную функцию.

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...