2010-01-20 14 views
7

Ecco un plugin per jQuery molto bello, molto simile a quello che usano qui su SO. Il problema per me è che lo usa per convertire il tempo.jQuery Tempo fa da un timestamp?

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

che sarebbe grande se non che ho il tempo negozio sul mio sito in UTC timestamp e non come un tempo formattato, c'è un modo per convertire qualcosa di simile ad usare un timestamp? So che in PHP posso convertire il mio timestamp in questo formato ma sembra eccessivo con la conversione di un sacco di volte su 1 pagina in PHP. Potrei sbagliarmi, chiunque altro lo fa in jQuery ma dal vero timestamp?

Anche io attualmente lo faccio in PHP su un sito per mostrare "2 ore 4 minuti fa", ma sarebbe meglio usare javascript per questo invece di 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); 

risposta

8

Ho avuto lo stesso problema. Sto usando i timestamp Unix generati da PHP, quindi ho deciso di fare un rapido hack ed estendere la funzione di parsing di jQuery timeago per gestire anche i timestamp. Funziona come un fascino. Basta cercare la funzione Parse intorno alla riga 79 nel file jquery.timeago.js e sostituirla con:

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

Esattamente quello che stavo cercando grazie. –

+0

Questo è fantastico, esattamente quello che volevo fare. Grazie per la condivisione! –

+0

+1 Questo dovrebbe essere più ottimizzato rispetto all'altra risposta! –

-1

Sarebbe meglio utilizzare entrambi, ma non è necessario renderlo dinamico con JS.

Infatti, ho visto questo comportamento solo su Facebook.

Inoltre, sei a conoscenza del fatto che il tag <time> è HTML5? Potrebbe creare alcune incompatibilità.

+0

c'è un modo per aggiornarlo? – Antonio

2

Mi piace usare DateJS.com che è una libreria javascript data/ora. Si può fare cose interessanti come questo (display 2 ore fa in un <span id='myfield'></span>):

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

Per l'amor di Dio, deve essere in grado di usare "unix timestamp", il timeago è già sufficiente ed è meglio di date.js se si vogliono usare le date. –

3

Qui c'è qualcosa in JavaScript utilizzando nient'altro che timestamp Unix.

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

Ora, è possibile memorizzare un timestamp in una variabile JavaScript nello stesso ambito come la funzione "timeago", o il vostro possibile memorizzarlo in un elemento HTML. Come accennato, l'elemento time è un elemento HTML 5. Si potrebbe fare qualcosa di simile:


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

Allora forse si dispone di un commento oggetto simile a:


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

Si potrebbe quindi ottenere il timestamp per un commento di (supponendo jQuery in quanto lei ha citato esso):


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

È un po 'hacker, ma funzionerebbe (se l'avessi fatto bene).

Problemi correlati