web-dev-qa-db-fra.com

Bibliothèque Javascript pour un formatage de date relatif convivial

Je voudrais afficher certaines dates par rapport à la date actuelle dans un format convivial.

Exemples de dates relatives respectueuses de l'homme:

  • Il y a 10 secondes
  • Dans 20 minutes
  • il y a 1 jour
  • Il y a 5 semaines
  • il y a 2 mois

Conservez fidèlement le plus grand ordre de grandeur (et de préférence, augmentez les unités lorsque vous passez 2 unités - 5 semaines au lieu de 1 mois).

Bien que je puisse vivre avec une bibliothèque qui avait moins de contrôle et des dates encore plus conviviales comme:

  • hier
  • demain
  • la semaine dernière
  • il y a quelques minutes
  • dans quelques heures

Des bibliothèques populaires pour cela?

88
rampion

Depuis que j'ai écrit cette réponse, une bibliothèque bien connue est moment.js .


Il y a bibliothèques disponibles , mais il est trivial de le mettre en œuvre vous-même. Il suffit d'utiliser une poignée de conditions.

Supposons que date soit un objet instancié Date pour la période à laquelle vous souhaitez effectuer une comparaison.

// 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';
}

Vous devrez adapter ceci pour gérer les dates futures.

84
alex

J'ai écrit moment.js , une bibliothèque de dates qui fait cela. Il s'agit de 5 Ko (2011) 52 Ko (2019), et fonctionne dans les navigateurs et dans le nœud. C'est aussi probablement la bibliothèque de date la plus populaire et la plus célèbre pour JavaScript.

Il supporte timeago, le formatage, l'analyse syntaxique, l'interrogation, la manipulation, l'i18n, etc.

Le timeago (heure relative) des dates passées est effectué avec moment().fromNow() . Par exemple, pour afficher le 1er janvier 2019 au format timeago:

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

Les chaînes timeago sont personnalisables avec moment.updateLocale() , afin que vous puissiez les modifier à votre guise.

Les seuils ne correspondent pas à ce que demande la question ("5 semaines" vs "1 mois"), mais il est indiqué quelle chaîne est utilisée pour quelle plage de temps.

78
timrwood

sugar.js possède d'excellentes fonctions de formatage de date.

En plus de cela, il fournit également des fonctions d'usage général communes telles que le formatage de chaîne, le formatage de nombre, etc., qui sont pratiques à utiliser.

15
Hendy Irawan

Voici quelque chose de John Resig - http://ejohn.org/blog/javascript-pretty-date/

EDIT (27/06/2014): Suite du commentaire de Sumurai8 - bien que la page liée fonctionne toujours, voici l'extrait pour le pretty.js lié à l'article ci-dessus:

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);
    });
};

Utilisation:

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

Extrait de l'article sur l'utilisation:

Exemple d'utilisation

Dans les exemples suivants, je fais en sorte que toutes les ancres sur le site, qui ont un titre avec une date, aient une jolie date comme texte intérieur. De plus, je continue à mettre à jour les liens toutes les 5 secondes après le chargement de la page.

Avec 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);

Avec jQuery:

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

Faiz: Modifications du code original, corrections de bugs et améliorations.

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;
}
13
Hari Pachuveetil

Ce script js est très gentil. Tout ce que vous avez à faire est de l'exécuter. Toutes les balises <time> Seront remplacées par des dates relatives et mises à jour toutes les quelques minutes, de sorte que l'heure relative sera toujours à jour.

http://timeago.yarp.com/

4
boreq

On dirait que vous pourriez utiliser http://www.datejs.com/

Ils ont un exemple sur la page principale qui fait exactement ce que vous décrivez!

EDIT: En fait, je pense avoir inversé votre question dans ma tête. Dans tous les cas, je pense que vous pourriez vérifier car c'est de toute façon une très bonne bibliothèque!

EDIT x2: Je vais faire écho à ce que les autres ont dit http://momentjs.com/ est probablement le meilleur choix disponible pour le moment.

EDIT x3: Je n'ai pas utilisé date.js depuis plus d'un an. J'utilise exclusivement momentjs pour tous mes besoins liés aux rendez-vous.

4
RoboKozo

voici un exemple de sucre vs moment: pour un calendrier qui affiche les semaines, j'avais besoin de la valeur lundi dernier:

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

Je préfère de loin le sucre et après quelques mois avec moment.js, je passe maintenant à sugar.js. il est plus clair et s’intègre parfaitement à la classe Date de Javascripts.

Les cas OP sont couverts par les deux bibliothèques, pour sugar.js voir http://sugarjs.com/dates

4
citykid