2010-01-20 3 views
7

Ниже приведено хорошее плагин для jQuery, очень похожий на то, что они используют здесь на SO. Проблема для меня в том, что она использует это для преобразования времени.jQuery Время от времени?

<time class="timeago" datetime="2008-07-17T09:24:17Z">July 17, 2008</time> 

Это было бы замечательно, за исключением, что я время магазина на моем сайте в формате UTC метки времени, а не как отформатированный время, есть способ, чтобы преобразовать что-то вроде этого, чтобы использовать метку времени? Я знаю, что в PHP я мог бы преобразовать свою временную метку в этот формат, но кажется, что она переполнена конверсией LOT раз на 1 странице в PHP. Я могу ошибаться, кто-то другой делает это в jquery, но с реальной отметки времени?

Также я в настоящее время делаю это в PHP на сайте, чтобы показать «2 часа 4 минуты назад», но было ли лучше использовать javascript для этого вместо PHP?

/* 
* timeago: a jQuery plugin, version: 0.8.1 (2010-01-04) 
* @requires jQuery v1.2.3 or later 
* 
* Timeago is a jQuery plugin that makes it easy to support automatically 
* updating fuzzy timestamps (e.g. "4 minutes ago" or "about 1 day ago"). 
* 
* For usage and examples, visit: 
* http://timeago.yarp.com/ 
* Copyright (c) 2008-2010, Ryan McGeary (ryanonjavascript -[at]- mcgeary [*dot*] org) 
*/ 
(function($) { 
    $.timeago = function(timestamp) { 
    if (timestamp instanceof Date) return inWords(timestamp); 
    else if (typeof timestamp == "string") return inWords($.timeago.parse(timestamp)); 
    else return inWords($.timeago.datetime(timestamp)); 
    }; 
    var $t = $.timeago; 

    $.extend($.timeago, { 
    settings: { 
     refreshMillis: 60000, 
     allowFuture: false, 
     strings: { 
     prefixAgo: null, 
     prefixFromNow: null, 
     suffixAgo: "ago", 
     suffixFromNow: "from now", 
     ago: null, // DEPRECATED, use suffixAgo 
     fromNow: null, // DEPRECATED, use suffixFromNow 
     seconds: "less than a minute", 
     minute: "about a minute", 
     minutes: "%d minutes", 
     hour: "about an hour", 
     hours: "about %d hours", 
     day: "a day", 
     days: "%d days", 
     month: "about a month", 
     months: "%d months", 
     year: "about a year", 
     years: "%d years" 
     } 
    }, 
    inWords: function(distanceMillis) { 
     var $l = this.settings.strings; 
     var prefix = $l.prefixAgo; 
     var suffix = $l.suffixAgo || $l.ago; 
     if (this.settings.allowFuture) { 
     if (distanceMillis < 0) { 
      prefix = $l.prefixFromNow; 
      suffix = $l.suffixFromNow || $l.fromNow; 
     } 
     distanceMillis = Math.abs(distanceMillis); 
     } 

     var seconds = distanceMillis/1000; 
     var minutes = seconds/60; 
     var hours = minutes/60; 
     var days = hours/24; 
     var years = days/365; 

     var words = seconds < 45 && substitute($l.seconds, Math.round(seconds)) || 
     seconds < 90 && substitute($l.minute, 1) || 
     minutes < 45 && substitute($l.minutes, Math.round(minutes)) || 
     minutes < 90 && substitute($l.hour, 1) || 
     hours < 24 && substitute($l.hours, Math.round(hours)) || 
     hours < 48 && substitute($l.day, 1) || 
     days < 30 && substitute($l.days, Math.floor(days)) || 
     days < 60 && substitute($l.month, 1) || 
     days < 365 && substitute($l.months, Math.floor(days/30)) || 
     years < 2 && substitute($l.year, 1) || 
     substitute($l.years, Math.floor(years)); 

     return $.trim([prefix, words, suffix].join(" ")); 
    }, 
    parse: function(iso8601) { 
     var s = $.trim(iso8601); 
     s = s.replace(/-/,"/").replace(/-/,"/"); 
     s = s.replace(/T/," ").replace(/Z/," UTC"); 
     s = s.replace(/([\+-]\d\d)\:?(\d\d)/," $1$2"); // -04:00 -> -0400 
     return new Date(s); 
    }, 
    datetime: function(elem) { 
     // jQuery's `is()` doesn't play well with HTML5 in IE 
     var isTime = $(elem).get(0).tagName.toLowerCase() == 'time'; // $(elem).is('time'); 
     var iso8601 = isTime ? $(elem).attr('datetime') : $(elem).attr('title'); 
     return $t.parse(iso8601); 
    } 
    }); 

    $.fn.timeago = function() { 
    var self = this; 
    self.each(refresh); 

    var $s = $t.settings; 
    if ($s.refreshMillis > 0) { 
     setInterval(function() { self.each(refresh); }, $s.refreshMillis); 
    } 
    return self; 
    }; 

    function refresh() { 
    var data = prepareData(this); 
    if (!isNaN(data.datetime)) { 
     $(this).text(inWords(data.datetime)); 
    } 
    return this; 
    } 

    function prepareData(element) { 
    element = $(element); 
    if (element.data("timeago") === undefined) { 
     element.data("timeago", { datetime: $t.datetime(element) }); 
     var text = $.trim(element.text()); 
     if (text.length > 0) element.attr("title", text); 
    } 
    return element.data("timeago"); 
    } 

    function inWords(date) { 
    return $t.inWords(distance(date)); 
    } 

    function distance(date) { 
    return (new Date().getTime() - date.getTime()); 
    } 

    function substitute(stringOrFunction, value) { 
    var string = $.isFunction(stringOrFunction) ? stringOrFunction(value) : stringOrFunction; 
    return string.replace(/%d/i, value); 
    } 

    // fix for IE6 suckage 
    document.createElement('abbr'); 
    document.createElement('time'); 
})(jQuery); 

ответ

8

У меня была та же проблема. Я использую временные метки Unix, которые генерируются на PHP, поэтому я решил сделать быстрый взлом и расширить функцию синтаксического анализа jQuery timeago для дополнительной обработки временных меток. Работает как шарм. Просто найдите функцию Parse по строке 79 в файле jquery.timeago.js и замените ее на следующее:

parse: function(iso8601) { 
    if ((iso8601 - 0) == iso8601 && iso8601.length > 0) { // Checks if iso8601 is a unix timestamp 
    var s = new Date(iso8601); 
    if (isNaN(s.getTime())) { // Checks if iso8601 is formatted in milliseconds 
     var s = new Date(iso8601 * 1000); //if not, add milliseconds 
    } 
    return s; 
    } 

    var s = $.trim(iso8601); 
    s = s.replace(/-/,"/").replace(/-/,"/"); 
    s = s.replace(/T/," ").replace(/Z/," UTC"); 
    s = s.replace(/([\+-]\d\d)\:?(\d\d)/," $1$2"); // -04:00 -> -0400 
    return new Date(s); 
}, 
+0

Именно то, что я искал благодаря. –

+0

Это потрясающе, именно то, что я хотел сделать. Спасибо, что поделился! –

+0

+1 Это должно быть больше, чем другой ответ! – 2014-08-25 07:10:44

-1

Было бы лучше использовать оба варианта, но нет необходимости делать его динамичным с помощью JS.

Фактически, я видел это поведение только в Facebook.

Также вы хорошо знаете, что тег <time> является HTML5? Это может создать несколько несовместимостей.

+0

есть способ автоподвести его? – Antonio

2

Мне нравится использовать DateJS.com, который является библиотекой javascript для даты/времени. Вы можете сделать такие вещи, как этот (дисплей 2 часа назад в <span id='myfield'></span>):

$('#myfield').text((2).hours().ago().toString("HH:mm")); 
+0

Ради Бога, он должен иметь возможность использовать «временные метки unix», timeago уже достаточно и лучше, чем date.js, если вы хотите использовать даты. – 2014-08-25 07:12:32

3

Вот что-то в JavaScript, не используя ничего, кроме Unix временных меток.

var d1; 
var d2; 
d1 = (new Date()).getTime(); setTimeout(function() { d2 = (new Date()).getTime(); }, 5000); 
var secondsElapsed = (d2 - d1)/1000; 
secondsElapsed; // 5 seconds 

Теперь вы можете либо сохранить метку времени в переменной JavaScript в том же объеме, как ваша функция «timeago», или ваш может хранить его в HTML-элемент. Как уже упоминалось, элемент time является элементом HTML 5. Вы могли бы сделать что-то вроде:


<p class="timestamp" style="display: none;">123456</p> 

Тогда, может быть, у вас есть комментарий пункт как:


<div class="comment"> 
    <p>Lorem ipsum et dolor...</p> 
    <p class="timestamp" style="display: none;">123456</p> 
</div> 

Вы могли бы получить метку времени для комментария на (при условии, JQuery, так как вы упоминали):


var tstamps = $('.comment .timestamp'); // array of comment timestamps 
var timeago = ((new Date()).getTime() - tstamps[0].html())/1000; 

Это немного хакерский, но он будет работать (если бы я сделал это правильно).

Смежные вопросы