Бібліотека Javascript для дружнього форматування відносної дати, зручного для людини [закрито]


94

Я хотів би відобразити деякі дати щодо поточної дати у зручному для людини форматі.

Приклади відносних дат, сприятливих для людини:

  • 10 секунд тому
  • Через 20 хвилин
  • 1 день тому
  • 5 тижнів тому
  • 2 місяці тому

В основному сумлінно зберігаючи найвищий порядок (і переважно, зміщуючи одиниці лише при проходженні 2 з цих одиниць - 5 тижнів замість 1 місяця).

Хоча я міг жити з бібліотекою, яка мала менший контроль і навіть більш дружні побачення, такі як:

  • вчора
  • завтра
  • минулого тижня
  • кілька хвилин тому
  • через пару годин

Будь-які популярні бібліотеки для цього?


Чому "1 день тому" більше "привітний для людей", ніж просто представлення фактичної дати та часу?
RobG

5
@RobG Я б сказав, що це більше про те, щоб уникнути перемикання контекстів, наприклад, на сторінці, яка є переважно текстовою та читається, контекстний перехід на, наприклад, mm / dd / yy, може спричинити паузу. У таблиці даних використання цього формату може бути більш читабельним. Це також залежить від того, що читачеві потрібно робити з датою, наприклад, "чи це сталося n днів тому" чи "це сталося до 1.01.1972 р.", Чи підходить воно чи іншим чином відповідає контексту читача.
wprl

Можливо, але заплутано бачити список подій як "Вчора ... 3 дні тому ... 10 / травень ...". Мені все одно потрібно перетворити їх на дати в голові, щоб сфотографувати, коли вони відбулися. Дати стислі та точні, значення "давно" - розмовні, не мають точності і, як правило, корисні лише з пов'язаною датою. Можливо, це тільки я, а може й ні. :-)
RobG

6
Я б сказав, це залежить від контексту. Зрештою, ви б не сказали, що "я пішов на риболовлю 17 лютого 2014 року", якби це було насправді вчора. Там значно більше мозкової паузи. Цей текст ідеально підходить для переліку останніх подій.
Саймон Вільямс

2
@RobG Думають, що подібні люди, такі як ми, не звичайні люди.

Відповіді:


92

З тих пір, як я написав цю відповідь, добре відома бібліотека є moment.js .


Є бібліотеки , але реально це реалізувати самостійно. Просто використовуйте кілька умов.

Припустимо date, це Dateоб'єкт, який створюється миттєво, за той час, з яким ви хочете порівняти.

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

Вам потрібно буде адаптувати це, щоб обробляти майбутні дати.


9
Вчора до останньої півночі, а не між 24 годин і 48 годин тому.
mxcl

Шахта @mmaclaurin ніколи не мала бути повноцінним рішенням, а лише вказівником у правильному напрямку. Я зроблю замітку, щоб пізніше її оновити, або, якщо ви хочете, сміливо відредагуйте відповідь.
alex

Будь ласка, також подивіться на date-fns ! Це чудова бібліотека, якщо ви хочете, щоб база вашого коду була невеликою, оскільки вона має набагато менший слід, ніж momentjs!
mesqueeb

1
Я змінив цей код , щоб зробити щебетати стиль getTimeAgoфункції gist.github.com/pomber/6195066a9258d1fb93bb59c206345b38
pomber

85

Я написав moment.js , бібліотеку дат, яка це робить. Це приблизно 5KB (2011) 52KB (2019) і працює в браузерах та в Node. Це також, мабуть, найпопулярніша і найвідоміша бібліотека дат для JavaScript.

Він підтримує timeago, форматування, аналіз, запити, маніпулювання, i18n тощо.

Timeago (відносний час) для дат у минулому робиться за допомогою moment().fromNow(). Наприклад, для відображення 1 січня 2019 року у форматі timeago:

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

Рядки тимгаго налаштовуються за допомогою moment.updateLocale(), тож ви можете змінити їх, як вам здається , що потрібно.

Обмеження не вимагає запитання ("5 тижнів" проти "1 місяць"), але задокументовано, які рядки використовуються для якого періоду часу.


1
Похвала за те, що вона працює в браузері та на вузлі !!!!
wprl

48
ха, однак, оновлення розміру!
Askdesigners

1
Будь ласка, також подивіться на date-fns ! Це чудова бібліотека, якщо ви хочете, щоб база вашого коду була невеликою, оскільки вона має набагато менший слід, ніж momentjs!
mesqueeb

Наскільки хороша ця бібліотека, відповідь не включає пояснення, як відформатувати номер у зручній для людини спосіб, використовуючи її
Code Whisperer

16

Ось щось із Джона Резіга - http://ejohn.org/blog/javascript-pretty-date/

EDIT (27.06.2014): Після отримання коментаря від Sumurai8 - хоча пов’язана сторінка все ще працює, ось уривок доpretty.js посилання на з статті вище:

досить.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);
    });
};

Використання:

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

Витяг із статті про використання:

Приклад використання

У наступних прикладах я роблю, що всі прив’язки на сайті, які мають заголовок із датою, мають гарну дату як їх внутрішній текст. Крім того, я продовжую оновлювати посилання кожні 5 секунд після завантаження сторінки.

За допомогою 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);

За допомогою jQuery:

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

Faiz: Вніс деякі зміни в оригінальний код, виправлення помилок та вдосконалення.

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
Привіт, Флойде, я додав деякі зміни (виправлення помилок, вдосконалення) у вашу відповідь. Сподіваюся, ви не заперечуєте ..
Faiz

Хороший! Але не працюйте з числовим типом часової позначки, можливо, вам потрібен кращий фільтр, наприклад, якщо if (typeof time == 'string') {time = time.replace (/ - / g, "/").replace(/ evidenceTZSense/ г, "")); }
Артур Араужо

15

sugar.js має чудові функції форматування дати.

Мало того, він також забезпечує загальні функції загального призначення, такі як форматування рядків, форматування чисел тощо, які зручні у використанні.


1
погодьтеся, sugar.js тут заслуговує на більше уваги.
citykid

5

ось приклад цукру проти моменту: для календаря, що відображає тижні, мені потрібно було значення останнього понеділка:

moment.js

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

цукор.js

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

Я набагато віддаю перевагу цукру, і через кілька місяців з moment.js тепер переходжу на sugar.js. він чіткіший і добре інтегрується з класом Дата Javascripts '.

Випадки роботи з ОП охоплені обома проблемами, див. Http://sugarjs.com/dates


4

Цей js-сценарій дуже приємний. Все, що вам потрібно зробити - це виконати його. Всі<time> теги будуть змінені на відносні дати та оновлюватися кожні кілька хвилин, тому відносний час завжди буде актуальним.

http://timeago.yarp.com/


1
Я думаю, що це найкраще рішення. Бібліотека ведеться дуже активно, вона базується на коді Resig / натхненна нею, вона дуже мала, має безліч локалізацій, інтегрувати її просто.
Джон Бачір

4

Здається, ви можете використовувати http://www.datejs.com/

Вони мають приклад на головній сторінці, який робить саме те, що ви описуєте!

EDIT: Насправді, я думаю, я змінив ваше питання в голові. У будь-якому випадку, я думаю, ви могли це перевірити, оскільки це все-таки чудова бібліотека!

EDIT x2: Я повторюю те, що сказали інші http://momentjs.com/ - це, мабуть, найкращий вибір, доступний зараз.

EDIT x3: я не використовував date.js більше року. Я використовую виключно momentjs для всіх моїх потреб, пов'язаних з датами.


Приємна пропозиція lib. Інтернаціоналізація, безумовно, плюс.
Стівен

Date.js також була моєю першою думкою, але я не бачу ніякого способу перейти від номера до формату, хоча це може бути десь сховано в документах.
чемпіон

Відомо, що Date.js має серйозні помилки, і йому не можна довіряти у виробничих умовах. Багато фреймворків переходять з Date.js на Moment.js
Джон Заброскі

Я дізнався , важкий шлях , що datejs не працює на Linux :(
жир Fantasma
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.