Почему этот DateParser не работает в Safari? - PullRequest
2 голосов
/ 22 сентября 2010

Я отображаю этот объект JSON:

[{"created_at":"2010-09-21T20:41:28Z","subject":"hello world"}]

Затем я использую этот анализатор даты для его анализа (см. Ниже), но он работает только в Chrome 6.0.4, Firefox 3.6.8, но НЕ в Safari 5.0.2 --- Я получаю ошибки NaN. Что дает?

 Date.prototype.toRelativeTime = function(now_threshold) {
 var delta = new Date() - this;

 now_threshold = parseInt(now_threshold, 10);

 if (isNaN(now_threshold)) {
   now_threshold = 0;
 }

 if (delta <= now_threshold) {
  return 'Just now';
 }

 var units = null;
 var conversions = {
   millisecond: 1, // ms    -> ms
   second: 1000,   // ms    -> sec
   minute: 60,     // sec   -> min
   hour:   60,     // min   -> hour
   day:    24,     // hour  -> day
   month:  30,     // day   -> month (roughly)
   year:   12      // month -> year
 };

 for (var key in conversions) {
   if (delta < conversions[key]) {
     break;
    } else {
     units = key; // keeps track of the selected key over the iteration
     delta = delta / conversions[key];
   }
 }

 // pluralize a unit when the difference is greater than 1.
    delta = Math.floor(delta);
 if (delta !== 1) { units += "s"; }
 return [delta, units, "ago"].join(" ");
  };

/*
 * Wraps up a common pattern used with this plugin whereby you take a String
* representation of a Date, and want back a date object.
*/
  Date.fromString = function(str) {
      return new Date(Date.parse(str));
  };

Ответы [ 3 ]

4 голосов
/ 22 сентября 2010

Проблема в том, что поддержка конструктора Date для ISO 8601 присутствует не во всех веб-браузерах. Вы можете сделать следующее:

Date.prototype.setISO8601 = function (string) {
    var regexp = "([0-9]{4})(-([0-9]{2})(-([0-9]{2})" +
        "(T([0-9]{2}):([0-9]{2})(:([0-9]{2})(\.([0-9]+))?)?" +
        "(Z|(([-+])([0-9]{2}):([0-9]{2})))?)?)?)?";
    var d = string.match(new RegExp(regexp));

    var offset = 0;
    var date = new Date(d[1], 0, 1);

    if (d[3]) { date.setMonth(d[3] - 1); }
    if (d[5]) { date.setDate(d[5]); }
    if (d[7]) { date.setHours(d[7]); }
    if (d[8]) { date.setMinutes(d[8]); }
    if (d[10]) { date.setSeconds(d[10]); }
    if (d[12]) { date.setMilliseconds(Number("0." + d[12]) * 1000); }
    if (d[14]) {
        offset = (Number(d[16]) * 60) + Number(d[17]);
        offset *= ((d[15] == '-') ? 1 : -1);
    }

    offset -= date.getTimezoneOffset();
    time = (Number(date) + (offset * 60 * 1000));
    this.setTime(Number(time));
}

тогда ваш код может выглядеть так:

var d = new Date("2010-09-13T11:51:50.9418504+02:00");
if (isNaN(d)) {
    //alert("Date constructor not support ISO8601!");
    d = new Date();
    d.setISO8601("2010-09-13T11:51:50.9418504+02:00");
}

Код не от меня. Я нашел его в Интернете, но не смог найти первоисточник.

1 голос
/ 02 декабря 2012

Я хотел бы добавить несколько слов к первому ответу:

Прежде всего, ответ идеален. Я надеюсь, что кто-то может рассказать мне больше об его источнике?

Во-вторых, в регулярных выражениях есть ошибки:

  • Точка миллисекунды во времени не указана правильно
  • регулярное выражение не проверяет всю строку. В моем случае я получил результат, даже когда часовой пояс не определен правильно
  • это подводит меня к третьей проблеме: стандарт ISO8601 позволяет опускать символы ":" и "-".

Я исправил регулярное выражение, за исключением третьего пункта (из-за нехватки времени для тестирования):

var regexp = "^([0-9]{4})(-([0-9]{2})(-([0-9]{2})" +
    "(T([0-9]{2}):([0-9]{2})(:([0-9]{2})(\\.([0-9]+))?)?" +
    "(Z|(([-+])([0-9]{2}):?([0-9]{2})))?)?)?)?$";
0 голосов
/ 22 сентября 2010
Tue, 21 Sep 2010 20:06:45 UTC +00:00

- это удобочитаемое представление, и ActiveSupport никогда не будет использовать этот формат для преобразования дат в JSON, если вы не исправите его (но не рекомендуется).

Однако вы можете использовать опцию config.active_support.use_standard_json_time_format, чтобы переключать стандартный формат времени json . Если true, Rails будет использовать XML-подобное представление даты. В противном случае он будет использовать пользовательский формат.

Вот исходный код

class Time
  def as_json(options = nil) #:nodoc:
    if ActiveSupport.use_standard_json_time_format
      xmlschema
    else
      %(#{strftime("%Y/%m/%d %H:%M:%S")} #{formatted_offset(false)})
    end
  end
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...