Бібліотека 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.