Libreria Javascript per la formattazione della data relativa a misura d'uomo [chiusa]


94

Vorrei visualizzare alcune date relative alla data corrente in un formato a misura d'uomo.

Esempi di date relative a misura d'uomo:

  • 10 secondi fa
  • Tra 20 minuti
  • 1 giorno fa
  • 5 settimane fa
  • 2 mesi fa

Fondamentalmente preservando fedelmente l'ordine di grandezza più alto (e preferibilmente, spostando le unità solo quando si superano 2 di quelle unità - 5 settimane invece di 1 mese).

Anche se potrei vivere con una biblioteca che aveva meno controllo e appuntamenti ancora più amichevoli come:

  • ieri
  • Domani
  • la settimana scorsa
  • pochi minuti fa
  • in un paio d'ore

Ci sono biblioteche popolari per questo?


Perché "1 giorno fa" è più "umano" della semplice presentazione della data e dell'ora effettive?
RobG

5
@ RobG direi che si tratta più di evitare il cambio di contesto, ad esempio in una pagina che è principalmente testo e viene letta, il cambio di contesto ad esempio mm / gg / aa può causare una pausa. In una tabella di dati, l'utilizzo di quel formato potrebbe essere più leggibile. Dipende anche da ciò che il lettore deve fare con la data, ad esempio se "questo è accaduto n giorni fa" o "questo è accaduto prima dell'1 / 1/1972" è utilizzabile o altrimenti appropriato al contesto del lettore.
wprl

Forse, ma è fonte di confusione vedere un elenco di eventi come "Ieri ... 3 giorni fa ... 10 / maggio ...". Ho ancora bisogno di convertirli tutti in date nella mia testa per avere un'immagine di quando si sono verificati. Le date sono concise e precise, i valori di "tempo fa" sono colloquiali, mancano di precisione e di solito sono utili solo con la data associata. Forse sono solo io, ma forse no. :-)
RobG

6
Direi che dipende dal contesto. Dopotutto, non diresti "Sono andato a pescare il 17 febbraio 2014" se fosse ieri. C'è molto di più di una pausa cerebrale lì. Questo tipo di testo è perfetto per un elenco di eventi recenti.
Simon Williams

2
@ RobG Solo i nerd come noi la pensano così non le persone normali.

Risposte:


92

Da quando ho scritto questa risposta, una libreria ben nota disponibile è moment.js .


Sono disponibili librerie , ma è banale implementarle da soli. Usa solo una manciata di condizioni.

Supponi che datesia un Dateoggetto istanziato per il tempo con cui vuoi fare un confronto.

// Make a fuzzy time
var delta = Math.round((+new Date - date) / 1000);

var minute = 60,
    hour = minute * 60,
    day = hour * 24,
    week = day * 7;

var fuzzy;

if (delta < 30) {
    fuzzy = 'just then.';
} else if (delta < minute) {
    fuzzy = delta + ' seconds ago.';
} else if (delta < 2 * minute) {
    fuzzy = 'a minute ago.'
} else if (delta < hour) {
    fuzzy = Math.floor(delta / minute) + ' minutes ago.';
} else if (Math.floor(delta / hour) == 1) {
    fuzzy = '1 hour ago.'
} else if (delta < day) {
    fuzzy = Math.floor(delta / hour) + ' hours ago.';
} else if (delta < day * 2) {
    fuzzy = 'yesterday';
}

Dovresti adattarlo per gestire le date future.


9
Ieri è prima dell'ultima mezzanotte, non tra 24 ore e 48 ore fa.
mxcl

@mmaclaurin La mia non è mai stata pensata per essere una soluzione completa, solo un puntatore nella giusta direzione. Farò una nota per aggiornarlo in seguito o, se lo desideri, sentiti libero di modificare la risposta.
alex

Dai un'occhiata anche a date-fns ! È un'ottima libreria se ti piace mantenere la tua base di codice piccola, perché ha un'impronta molto inferiore rispetto a momentjs!
mesqueeb

1
Ho cambiato questo codice per creare una getTimeAgofunzione in stile twitter gist.github.com/pomber/6195066a9258d1fb93bb59c206345b38
pomber

85

Ho scritto moment.js , una libreria di date che fa questo. Si tratta di circa 5 KB (2011) 52 KB (2019) e funziona nei browser e in Node. È anche probabilmente la libreria di date più popolare e famosa per JavaScript.

Supporta timeago, formattazione, analisi, query, manipolazione, i18n, ecc.

Timeago (tempo relativo) per le date nel passato è terminato moment().fromNow(). Ad esempio, per visualizzare il 1 ° gennaio 2019 nel formato timeago:

let date = moment("2019-01-01", "YYYY-MM-DD");
console.log(date.fromNow());
<script src="https://momentjs.com/downloads/moment.min.js"></script>

Le corde timeago sono personalizzabili con moment.updateLocale(), quindi puoi cambiarle come meglio credi.

Le interruzioni non sono ciò che la domanda richiede ("5 settimane" rispetto a "1 mese"), ma è documentato su quali stringhe vengono utilizzate per quale intervallo di tempo.


1
Complimenti per averlo fatto funzionare nel browser e nel nodo !!!!
wprl

48
ha quell'aggiornamento di dimensioni però!
Askdesigners

1
Dai un'occhiata anche a date-fns ! È un'ottima libreria se ti piace mantenere la tua base di codice piccola, perché ha un'impronta molto inferiore rispetto a momentjs!
mesqueeb

Per quanto buona sia questa libreria, la risposta non include una spiegazione su come formattare un numero in modo amichevole utilizzandolo
Code Whisperer

16

Ecco qualcosa dal John Resig - http://ejohn.org/blog/javascript-pretty-date/

EDIT (27/6/2014): in seguito al commento di Sumurai8 - sebbene la pagina collegata funzioni ancora, ecco l'estratto delpretty.js collegamento dell'articolo sopra:

pretty.js

/*
 * JavaScript Pretty Date
 * Copyright (c) 2011 John Resig (ejohn.org)
 * Licensed under the MIT and GPL licenses.
 */

// Takes an ISO time and returns a string representing how
// long ago the date represents.
function prettyDate(time) {
    var date = new Date((time || "").replace(/-/g, "/").replace(/[TZ]/g, " ")),
        diff = (((new Date()).getTime() - date.getTime()) / 1000),
        day_diff = Math.floor(diff / 86400);

    if (isNaN(day_diff) || day_diff < 0 || day_diff >= 31) return;

    return day_diff == 0 && (
    diff < 60 && "just now" || diff < 120 && "1 minute ago" || diff < 3600 && Math.floor(diff / 60) + " minutes ago" || diff < 7200 && "1 hour ago" || diff < 86400 && Math.floor(diff / 3600) + " hours ago") || day_diff == 1 && "Yesterday" || day_diff < 7 && day_diff + " days ago" || day_diff < 31 && Math.ceil(day_diff / 7) + " weeks ago";
}

// If jQuery is included in the page, adds a jQuery plugin to handle it as well
if (typeof jQuery != "undefined") jQuery.fn.prettyDate = function() {
    return this.each(function() {
        var date = prettyDate(this.title);
        if (date) jQuery(this).text(date);
    });
};

Utilizzo:

prettyDate("2008-01-28T20:24:17Z") // => "2 hours ago"
prettyDate("2008-01-27T22:24:17Z") // => "Yesterday"
prettyDate("2008-01-26T22:24:17Z") // => "2 days ago"
prettyDate("2008-01-14T22:24:17Z") // => "2 weeks ago"
prettyDate("2007-12-15T22:24:17Z") // => undefined

Estratto dall'articolo sull'utilizzo:

Utilizzo di esempio

Negli esempi seguenti faccio in modo che tutti gli ancoraggi sul sito, che hanno un titolo con una data, abbiano una bella data come testo interno. Inoltre, continuo ad aggiornare i collegamenti ogni 5 secondi dopo il caricamento della pagina.

Con JavaScript:

function prettyLinks(){
    var links = document.getElementsByTagName("a");
    for ( var i = 0; i < links.length; i++ )
        if ( links[i].title ) {
            var date = prettyDate(links[i].title);
            if ( date )
                links[i].innerHTML = date;
        }
}
prettyLinks();
setInterval(prettyLinks, 5000);

Con jQuery:

$("a").prettyDate();
setInterval(function(){ $("a").prettyDate(); }, 5000);

Faiz: ha apportato alcune modifiche al codice originale, correzioni di bug e miglioramenti.

function prettyDate(time) {
    var date = new Date((time || "").replace(/-/g, "/").replace(/[TZ]/g, " ")),
        diff = (((new Date()).getTime() - date.getTime()) / 1000),
        day_diff = Math.floor(diff / 86400);
    var year = date.getFullYear(),
        month = date.getMonth()+1,
        day = date.getDate();

    if (isNaN(day_diff) || day_diff < 0 || day_diff >= 31)
        return (
            year.toString()+'-'
            +((month<10) ? '0'+month.toString() : month.toString())+'-'
            +((day<10) ? '0'+day.toString() : day.toString())
        );

    var r =
    ( 
        (
            day_diff == 0 && 
            (
                (diff < 60 && "just now")
                || (diff < 120 && "1 minute ago")
                || (diff < 3600 && Math.floor(diff / 60) + " minutes ago")
                || (diff < 7200 && "1 hour ago")
                || (diff < 86400 && Math.floor(diff / 3600) + " hours ago")
            )
        )
        || (day_diff == 1 && "Yesterday")
        || (day_diff < 7 && day_diff + " days ago")
        || (day_diff < 31 && Math.ceil(day_diff / 7) + " weeks ago")
    );
    return r;
}

1
Ciao Floyd, ho aggiunto alcune modifiche (correzione di bug, miglioramenti) alla tua risposta. Spero non ti dispiaccia ..
Faiz

Buono! Ma non funziona con il tipo numerico timestamp, forse è necessario un filtro migliore come if (typeof time == 'string') {time = time.replace (/ - / g, "/").replace(/[TZ”/ g, "")); }
Arthur Araújo

15

sugar.js ha ottime funzioni di formattazione della data.

Non solo, fornisce anche funzioni generali comuni come formattazione di stringhe, formattazione di numeri, ecc. Che sono comode da usare.


1
d'accordo, sugar.js merita più attenzione qui.
citykid

5

ecco un esempio di zucchero vs momento: per un calendario che mostra le settimane, avevo bisogno dell'ultimo valore di lunedì:

moment.js

var m = moment().subtract("days", 1).sod().day(1) // returns a "moment"

sugar.js

var d = Date.past("monday") // returns a js Date object

Preferisco di gran lunga lo zucchero e dopo alcuni mesi con moment.js ora passo a sugar.js. è più chiaro e si integra bene con la classe Date di Javascripts.

I casi OP sono coperti da entrambe le librerie, per sugar.js vedere http://sugarjs.com/dates


4

Questo script js è molto carino. Tutto quello che devi fare è eseguirlo. Tutti i <time>tag verranno modificati in date relative e aggiornati ogni pochi minuti, quindi il tempo relativo sarà sempre aggiornato.

http://timeago.yarp.com/


1
Penso che questa sia la soluzione migliore. La libreria è mantenuta molto attivamente, è basata / ispirata al codice Resig, è molto piccola, ha tonnellate di localizzazioni, è semplice da integrare.
John Bachir,

4

Sembra che potresti usare http://www.datejs.com/

Hanno un esempio nella pagina principale che fa esattamente quello che stai descrivendo!

EDIT: In realtà, penso di aver ribaltato la tua domanda nella mia testa. In ogni caso, penso che potresti verificarlo perché è comunque una libreria davvero fantastica!

EDIT x2: farò eco a ciò che hanno detto gli altri http://momentjs.com/ è probabilmente la migliore scelta disponibile in questo momento.

EDIT x3: non uso date.js da oltre un anno. Uso esclusivamente momentjs per tutte le mie esigenze relative alla data.


Bel suggerimento di lib. L'internazionalizzazione sicuramente un plus.
Stephen

Date.js è stato anche il mio primo pensiero, ma non vedo alcun modo per passare dal numero al formato con esso, anche se potrebbe essere nascosto da qualche parte nei documenti.
rampion

Date.js è noto per avere gravi bug e non può essere considerato attendibile negli ambienti di produzione. Molti framework stanno passando da Date.js a Moment.js
John Zabroski

Ho imparato a mie spese che datejs non funziona su Linux :(
fat fantasma
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.