Biblioteka JavaScript do przyjaznego dla człowieka formatowania dat względnych [zamknięte]


95

Chciałbym wyświetlić niektóre daty jako względne do daty bieżącej w formacie przyjaznym dla człowieka.

Przykłady dat względnych przyjaznych człowiekowi:

  • 10 sekund temu
  • Za 20 minut
  • 1 dzień temu
  • 5 tygodni temu
  • 2 miesiące temu

Zasadniczo wierne zachowanie najwyższego rzędu wielkości (i preferencyjnie przesuwanie jednostek w górę tylko po przejściu 2 z tych jednostek - 5 tygodni zamiast 1 miesiąca).

Chociaż mógłbym żyć z biblioteką, która miała mniejszą kontrolę i jeszcze bardziej przyjazne randki, takie jak:

  • wczoraj
  • jutro
  • zeszły tydzień
  • kilka minut temu
  • za kilka godzin

Jakieś popularne biblioteki?


Dlaczego „1 dzień temu” jest bardziej „przyjazny dla człowieka” niż zwykłe przedstawienie rzeczywistej daty i godziny?
— RobG,

5
@RobG Powiedziałbym, że bardziej chodzi o unikanie przełączania kontekstów, np. Na stronie, która jest głównie tekstowa i jest czytana, zmiana kontekstu na np. Mm / dd / rr może spowodować pauzę. W tabeli danych użycie tego formatu może być bardziej czytelne. Zależy to również od tego, co czytelnik musi zrobić z datą, np. Czy „to wydarzyło się n dni temu” lub „to wydarzyło się przed 1 stycznia 1972 r.” Jest wykonalne lub w inny sposób odpowiednie w kontekście czytelnika.
— wprl

Być może, ale mylące jest zobaczenie listy wydarzeń jako „Wczoraj… 3 dni temu… 10 / Maj…”. Nadal muszę przekonwertować je wszystkie na daty w mojej głowie, aby uzyskać obraz, kiedy wystąpiły. Daty są zwięzłe i precyzyjne, wartości „sprzed czasu” są konwersacyjne, nieprecyzyjne i zwykle są pomocne tylko w przypadku powiązanej daty. Może to tylko ja, ale może nie. :-)
— RobG

6
Powiedziałbym, że zależy to od kontekstu. Przecież nie powiedzielibyście: „Poszedłem łowić 17 lutego 2014 roku”, gdyby to faktycznie było wczoraj. Tam jest znacznie więcej przerwy w mózgu. Ten rodzaj tekstu jest idealny na listę ostatnich wydarzeń.
— Simon Williams,

2
@RobG Tylko nerdy tacy jak my myślą w ten sposób, a nie normalni ludzie.

Odpowiedzi:


94

Odkąd napisałem tę odpowiedź, dobrze znaną dostępną biblioteką jest moment.js .


Biblioteki są dostępne , ale samodzielne wdrożenie jest trywialne. Po prostu użyj kilku warunków.

Załóżmy, że datejest to Dateobiekt, którego instancja ma miejsce w czasie, z którym chcesz dokonać porównania.

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

Będziesz musiał to dostosować, aby obsługiwać przyszłe daty.


9
Wczoraj jest przed ostatnią północą, a nie od 24 do 48 godzin temu.
— mxcl,

@mmaclaurin Mine nigdy nie miał być kompletnym rozwiązaniem, tylko wskazówką we właściwym kierunku. Zrobię notatkę, aby zaktualizować ją później, lub jeśli chcesz, możesz edytować odpowiedź.
— Alex

Proszę również spojrzeć na date-fns ! To świetna biblioteka, jeśli chcesz, aby Twoja baza kodu była niewielka, ponieważ zajmuje dużo mniej miejsca niż momentjs!
— mesqueeb

1
Zmieniłem ten kod dokonać styl twitter getTimeAgofunkcji gist.github.com/pomber/6195066a9258d1fb93bb59c206345b38
— pomber

87

Napisałem moment.js , bibliotekę dat, która to robi. Ma około 5 KB (2011) 52 KB (2019) i działa w przeglądarkach oraz w Node. Jest to również prawdopodobnie najpopularniejsza i najbardziej znana biblioteka dat dla JavaScript.

Obsługuje timeago, formatowanie, parsowanie, zapytania, manipulowanie, i18n itp.

Timeago (czas względny) dla dat z przeszłości jest zakończony moment().fromNow(). Na przykład, aby wyświetlić 1 stycznia 2019 r. W formacie timeago:

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

Ciągi timeago można dostosować za pomocą moment.updateLocale(), więc możesz je zmienić według własnego uznania.

Wartości graniczne nie są tym, czego żąda pytanie („5 tygodni” w porównaniu z „1 miesiącem”), ale jest udokumentowane, które ciągi znaków są używane w jakim przedziale czasu.


1
Brawa za sprawienie, by działał w przeglądarce i węźle !!!!
— wprl

50
ha ta aktualizacja rozmiaru!
— Askdesigners,

1
Proszę również spojrzeć na date-fns ! To świetna biblioteka, jeśli chcesz, aby Twoja baza kodu była niewielka, ponieważ zajmuje dużo mniej miejsca niż momentjs!
— mesqueeb

Chociaż ta biblioteka jest dobra, odpowiedź nie zawiera wyjaśnienia, jak sformatować liczbę w sposób przyjazny dla człowieka przy użyciu jej
— Zaklinacz kodu,

Czy zamierzasz również zaktualizować „wycofanie”? momentjs.com/docs/#/-project-status
— Juan De la Cruz

17

Oto coś z John Resig - http://ejohn.org/blog/javascript-pretty-date/

EDYCJA (27.06.2014): W związku z komentarzem Sumurai8 - chociaż strona, do której prowadzi łącze, nadal działa, oto fragment linkupretty.js do z powyższego artykułu:

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

Stosowanie:

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

Fragment artykułu o stosowaniu:

Przykładowe użycie

W poniższych przykładach wszystkie kotwice w witrynie, które mają tytuł z datą, mają ładną datę jako tekst wewnętrzny. Ponadto nadal aktualizuję linki co 5 sekund po załadowaniu strony.

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

Dzięki jQuery:

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

Faiz: Wprowadzono pewne zmiany w oryginalnym kodzie, poprawki błędów i ulepszenia.

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
Cześć Floyd, dodałem kilka zmian (poprawki błędów, ulepszenia) do Twojej odpowiedzi. Mam nadzieję, że nie masz nic przeciwko ...
— Faiz

Dobry! Ale nie pracuj z typem liczbowym znacznika czasu, może potrzebujesz lepszego filtra, takiego jak if (typeof time == 'string') {time = time.replace (/ - / g, "/").replace(/[TZ]/ g, „”)); }
— Arthur Araújo

Proszę, jak rozliczyć przyszłe daty? Jak za 2 dni.
— Ikenna Emman

15

Sugar.js ma świetne funkcje formatowania daty.

Co więcej, zapewnia również popularne funkcje ogólnego przeznaczenia, takie jak formatowanie ciągów, formatowanie liczb itp., Które są wygodne w użyciu.


1
zgadzam się, sugar.js zasługuje tutaj na więcej uwagi.
— citykid

5

tutaj przykład cukier vs moment: w przypadku kalendarza wyświetlającego tygodnie potrzebowałem wartości z ostatniego poniedziałku:

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

Wolę cukier i po kilku miesiącach z moment.js przechodzę teraz na sugar.js. jest bardziej przejrzysty i ładnie integruje się z klasą Date w Javascripts.

Przypadki OP są obsługiwane przez obie biblioteki, dla sugar.js patrz http://sugarjs.com/dates


4

Ten skrypt js jest bardzo fajny. Wszystko, co musisz zrobić, to go wykonać. Wszystkie <time>tagi zostaną zmienione na daty względne i aktualizowane co kilka minut, aby czas względny był zawsze aktualny.

http://timeago.yarp.com/


1
Myślę, że to najlepsze rozwiązanie. Biblioteka jest bardzo aktywnie utrzymywana, oparta na / inspirowana kodem Resiga, jest bardzo mała, ma mnóstwo lokalizacji, integracja jest banalna.
— John Bachir

4

Wygląda na to, że możesz użyć http://www.datejs.com/

Mają przykład na stronie głównej, który robi dokładnie to, co opisujesz!

EDYCJA: Właściwie myślę, że odwróciłem twoje pytanie w mojej głowie. W każdym razie myślę, że możesz to sprawdzić, ponieważ i tak jest to naprawdę świetna biblioteka!

EDYCJA x2: Powtórzę to, co powiedzieli inni, http://momentjs.com/ jest prawdopodobnie najlepszym dostępnym obecnie wyborem.

EDYCJA x3: Nie używałem date.js od ponad roku. Używam momentjs wyłącznie do wszystkich moich potrzeb związanych z randkami.


Niezła propozycja lib. Internacjonalizacja to zdecydowanie plus.
— Stephen

Date.js też był moją pierwszą myślą, ale nie widzę sposobu, aby przejść z tego numeru do formatu - chociaż może być ukryty gdzieś w dokumentach.
— rampion

Date.js jest znany z poważnych błędów i nie można mu ufać w środowiskach produkcyjnych. Wiele frameworków przechodzi z Date.js na Moment.js
— John Zabroski

Dowiedziałem się na własnej skórze, że datejs nie działa na Linuksie :(
— fat fantasma
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.