Javascript-Bibliothek zur benutzerfreundlichen relativen Datumsformatierung [geschlossen]

94

Ich möchte einige Daten relativ zum aktuellen Datum in einem benutzerfreundlichen Format anzeigen.

Beispiele für menschenfreundliche relative Daten:

  • Vor 10 Sekunden
  • In 20 Minuten
  • Vor 1 Tag
  • Vor 5 Wochen
  • Vor 2 Monaten

Grundsätzlich die höchste Größenordnung treu bewahren (und vorzugsweise nur Einheiten verschieben, wenn 2 dieser Einheiten überschritten werden - 5 Wochen statt 1 Monat).

Obwohl ich mit einer Bibliothek leben könnte, die weniger Kontrolle und noch freundlichere Daten hatte wie:

  • gestern
  • Morgen
  • letzte Woche
  • vor ein paar Minuten
  • in ein paar Stunden

Irgendwelche beliebten Bibliotheken dafür?

Rampion
quelle
Warum ist "vor 1 Tag" "menschenfreundlicher" als nur das tatsächliche Datum und die Uhrzeit anzugeben?
RobG
5
@RobG Ich würde sagen, es geht mehr darum, das Wechseln von Kontexten zu vermeiden, z. B. auf einer Seite, die hauptsächlich aus Text besteht und gelesen wird. Der Kontextwechsel auf z. B. mm / tt / jj kann eine Pause verursachen. In einer Datentabelle ist die Verwendung dieses Formats möglicherweise besser lesbar. Es hängt auch davon ab, was der Leser mit dem Datum zu tun hat, z. B. ob "dies geschah vor n Tagen" oder "dies geschah vor dem 1.1.1972" umsetzbar oder auf andere Weise dem Kontext des Lesers angemessen ist.
wprl
Vielleicht, aber es ist verwirrend, eine Liste von Ereignissen als "Gestern ... vor 3 Tagen ... 10 / Mai ..." zu sehen. Ich muss sie immer noch alle in Daten in meinem Kopf konvertieren, um ein Bild davon zu bekommen, wann sie aufgetreten sind. Daten sind präzise und präzise, ​​"Zeit vor" -Werte sind Konversationswerte, nicht genau und normalerweise nur mit dem zugehörigen Datum hilfreich. Vielleicht bin ich es nur, aber vielleicht auch nicht. :-)
RobG
6
Ich würde sagen, es hängt vom Kontext ab. Schließlich würde man nicht sagen "Ich bin am 17. Februar 2014 angeln gegangen", wenn das tatsächlich gestern wäre. Dort gibt es viel mehr eine Gehirnpause. Diese Art von Text ist perfekt für eine Liste der jüngsten Ereignisse.
Simon Williams
2
@RobG Nur Nerds wie wir denken so, keine normalen Leute.

Antworten:

92

Seit ich diese Antwort geschrieben habe, ist moment.js eine bekannte Bibliothek verfügbar .


Es sind Bibliotheken verfügbar , aber es ist trivial, diese selbst zu implementieren. Verwenden Sie einfach eine Handvoll Bedingungen.

Angenommen, es datehandelt sich um ein instanziiertes DateObjekt für die Zeit, mit der Sie einen Vergleich durchführen möchten.

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

Sie müssten dies anpassen, um zukünftige Daten zu verarbeiten.

Alex
quelle
9
Gestern ist vor der letzten Mitternacht, nicht zwischen 24 und 48 Stunden.
mxcl
@mmaclaurin Mine war nie als Komplettlösung gedacht, nur als Zeiger in die richtige Richtung. Ich mache mir eine Notiz, um sie später zu aktualisieren, oder wenn Sie möchten, können Sie die Antwort jederzeit bearbeiten.
Alex
Bitte schauen Sie sich auch date-fns an ! Es ist eine großartige Bibliothek, wenn Sie Ihre Codebasis klein halten möchten, da sie viel weniger Platz benötigt als momentjs!
Mesqueeb
1
Ich habe diesen Code geändert, um eine getTimeAgoFunktion im Twitter-Stil zu erstellen. Gist.github.com/pomber/6195066a9258d1fb93bb59c206345b38
pomber
85

Ich habe moment.js geschrieben , eine Datumsbibliothek , die dies tut. Es geht um 5 KB (2011) 52 KB (2019) und funktioniert in Browsern und in Node. Es ist wahrscheinlich auch die beliebteste und bekannteste Datumsbibliothek für JavaScript.

Es unterstützt Timeago, Formatieren, Parsen, Abfragen, Bearbeiten, i18n usw.

Timeago (relative Zeit) für Daten in der Vergangenheit ist erledigt mit moment().fromNow(). So zeigen Sie beispielsweise den 1. Januar 2019 im Timeago-Format an:

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

Die Timeago-Zeichenfolgen können mit angepasst werden moment.updateLocale(), sodass Sie sie nach Belieben ändern können.

Die Grenzwerte entsprechen nicht den Anforderungen der Frage ("5 Wochen" gegenüber "1 Monat"), es wird jedoch dokumentiert, welche Zeichenfolgen für welchen Zeitraum verwendet werden.

Timrwood
quelle
1
Ein großes Lob dafür, dass es in Browser und Knoten funktioniert !!!!
wprl
48
ha diese Größe Update obwohl!
Askdesigners
1
Bitte schauen Sie sich auch date-fns an ! Es ist eine großartige Bibliothek, wenn Sie Ihre Codebasis klein halten möchten, da sie viel weniger Platz benötigt als momentjs!
Mesqueeb
So gut diese Bibliothek auch ist, die Antwort enthält keine Erklärung, wie man eine Zahl auf menschenfreundliche Weise damit formatiert
Code Whisperer
16

Hier ist etwas von John Resig - http://ejohn.org/blog/javascript-pretty-date/

BEARBEITEN (27.06.2014): Nach dem Kommentar von Sumurai8 - obwohl die verlinkte Seite immer noch funktioniert, ist hier der Auszug für den pretty.jsverlinkten Artikel aus dem obigen Artikel:

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

Verwendung:

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

Auszug aus dem Artikel über die Verwendung:

Beispiel Verwendung

In den folgenden Beispielen mache ich, dass alle Anker auf der Site, die einen Titel mit einem Datum enthalten, ein hübsches Datum als inneren Text haben. Außerdem aktualisiere ich die Links weiterhin alle 5 Sekunden, nachdem die Seite geladen wurde.

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

Mit jQuery:

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

Faiz: Einige Änderungen am Originalcode, Fehlerbehebungen und Verbesserungen vorgenommen.

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;
}
Hari Pachuveetil
quelle
1
Hallo Floyd, ich habe Ihrer Antwort einige Änderungen (Fehlerbehebung, Verbesserungen) hinzugefügt. Hoffe es macht dir nichts aus ..
Faiz
Gut! Arbeiten Sie jedoch nicht mit dem numerischen Zeitstempeltyp, sondern benötigen Sie möglicherweise einen besseren Filter wie if (typeof time == 'string') {time = time.replace (/ - / g, "/").replace(/[TZ‹/ g))); }
Arthur Araújo
15

zucker.js hat großartige Datumsformatierungsfunktionen.

Darüber hinaus bietet es allgemeine Allzweckfunktionen wie Zeichenfolgenformatierung, Zahlenformatierung usw., die bequem zu verwenden sind.

Hendy Irawan
quelle
1
stimme zu, zucker.js verdient hier mehr Aufmerksamkeit.
Citykid
5

hier ein Beispiel für Zucker gegen Moment: Für einen Kalender, der Wochen anzeigt, brauchte ich den letzten Montagwert:

moment.js

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

Zucker.js

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

Ich bevorzuge Zucker und nach einigen Monaten mit moment.js wechsle ich jetzt zu zucker.js. Es ist klarer und lässt sich gut in die Date-Klasse von Javascripts integrieren.

OP-Fälle werden von beiden Bibliotheken abgedeckt. Zucker.js finden Sie unter http://sugarjs.com/dates

Stadtkind
quelle
4

Dieses JS-Skript ist sehr schön. Alles was Sie tun müssen, ist es auszuführen. Alle <time>Tags werden in relative Daten geändert und alle paar Minuten aktualisiert, sodass die relative Zeit immer auf dem neuesten Stand ist.

http://timeago.yarp.com/

Boreq
quelle
1
Ich denke, das ist die beste Lösung. Die Bibliothek wird sehr aktiv gepflegt, basiert auf / inspiriert von Resigs Code, ist sehr klein, hat unzählige Lokalisierungen und ist einfach zu integrieren.
John Bachir
4

Klingt so, als könnten Sie http://www.datejs.com/ verwenden.

Sie haben ein Beispiel auf der Hauptseite, das genau das tut, was Sie beschreiben!

EDIT: Eigentlich denke ich, ich habe Ihre Frage in meinem Kopf umgekehrt. Auf jeden Fall könnte man es sich ansehen, da es sowieso eine wirklich großartige Bibliothek ist!

EDIT x2: Ich werde wiederholen, was die anderen gesagt haben. Http://momentjs.com/ ist wahrscheinlich die derzeit beste Wahl.

EDIT x3: Ich habe date.js seit über einem Jahr nicht mehr verwendet. Ich verwende momentjs ausschließlich für alle meine datumsbezogenen Anforderungen.

RoboKozo
quelle
Netter lib Vorschlag. Internationalisierung definitiv ein Plus.
Stephen
Date.js war auch mein erster Gedanke, aber ich sehe keine Möglichkeit, damit von der Zahl zum Format zu gelangen - obwohl es möglicherweise irgendwo in den Dokumenten versteckt ist.
Rampion
Date.js weist bekanntermaßen schwerwiegende Fehler auf und kann in Produktionsumgebungen nicht als vertrauenswürdig eingestuft werden. Viele Frameworks wechseln von Date.js zu Moment.js
John Zabroski
Ich habe auf die harte Tour gelernt, dass Datejs unter Linux nicht funktioniert :(
Fat Fantasma