2010-01-20 10 views
7

Poniżej znajduje się naprawdę miła dawno temu wtyczka do jQuery, bardzo podobna do tego, czego używają tutaj na SO. Problem polega na tym, że używa tego do konwersji czasu.jQuery Czasu temu z timestamp?

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

To byłoby super z wyjątkiem, że czas przechowywania na moim miejscu w UTC datownik, a nie jako sformatowany czasie, czy jest jakiś sposób przekonwertować coś jak to użyć znacznika czasu? Wiem, że w PHP mogłem przekonwertować mój znacznik czasu do tego formatu, ale wydaje się, że przesadnie z konwersją wiele razy na 1 stronie w PHP. Mogę się mylić, czy ktoś inny robi to w jquery, ale z prawdziwego timestamp?

Również obecnie robię to w PHP na stronie, aby pokazać "2 godziny 4 minuty temu", ale czy lepiej byłoby użyć javascript dla tego zamiast 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); 

Odpowiedz

8

Miałem ten sam problem. Używam uniksowych znaczników czasu, które są generowane z PHP, więc zdecydowałem się zrobić szybki hack i rozszerzyć funkcję parsowania jQuery timeago do obsługi znaczników czasu dodatkowo. Działa jak marzenie. Po prostu wyszukaj funkcję Parse w linii 79 w pliku jquery.timeago.js i zamień ją na:

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

Dokładnie to, czego szukałem dzięki. –

+0

To jest niesamowite, dokładnie to, co chciałem zrobić. Dzięki za udostępnienie! –

+0

+1 Ten powinien być bardziej uprzywilejowany niż druga odpowiedź! –

-1

Byłoby lepiej używać obu, ale nie jest konieczne, aby było dynamiczne z JS.

Rzeczywiście, widziałem to tylko na Facebooku.

Czy wiesz, że tag <time> to HTML5? Może to doprowadzić do kilku nieskompatybilności.

+0

Czy istnieje sposób na automatyczne aktualizowanie? – Antonio

2

Lubię używać DateJS.com, która jest biblioteką javascript. Można zrobić fajne rzeczy tak (wyświetlacz 2 godziny temu w <span id='myfield'></span>):

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

Na litość boską, musi być w stanie używać "znaczników czasu unix", timeago już wystarcza i jest lepsze niż date.js, jeśli chcesz używać dat. –

3

Oto coś w JavaScript używając tylko znaczników czasu Uniksa.

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

Teraz, można przechowywać znacznikiem czasu w zmiennej JavaScript w takim samym zakresie jak swojej funkcji „timeago” lub twój może przechowywać go w elemencie HTML. Jak wspomniano, element time jest elementem HTML 5. Można zrobić coś takiego:


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

to może masz element komentarz jak:


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

Następnie można uzyskać znacznik czasu w komentarzu przez (zakładając jQuery skoro wspomniał):


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

To trochę hackish, ale to by działało (jeśli zrobiłem to dobrze).