인간 친화적 인 상대 날짜 형식을위한 자바 스크립트 라이브러리


94

사람에게 친숙한 형식으로 현재 날짜를 기준으로 일부 날짜를 표시하고 싶습니다.

인간 친화적 인 상대 날짜의 예 :

  • 10 초 전
  • 지금부터 20 분
  • 1 일 전
  • 5 주전
  • 2 달전

기본적으로 가장 높은 등급을 충실히 보존합니다 (그리고 선호도에 따라 해당 단위 중 2 개를 통과 할 때만 단위 이동-1 개월 대신 5 주).

통제력이 약하고 다음과 같은 친근한 날짜를 가진 도서관에서 살 수는 있지만

  • 어제
  • 내일
  • 지난주
  • 몇 분 전
  • 몇 시간 안에

이것에 대한 인기있는 도서관이 있습니까?


단순히 실제 날짜와 시간을 제시하는 것보다 "1 일 전"이 "인간 친화적"인 이유는 무엇입니까?
RobG

5
@RobG 대부분 텍스트이고 읽는 페이지에서 컨텍스트 전환을 피하는 것이 더 중요하다고 말하고 싶습니다. 컨텍스트를 mm / dd / yy로 전환하면 일시 중지 될 수 있습니다. 데이터 테이블에서 해당 형식을 사용하면 더 읽기 쉬울 수 있습니다. 또한 독자가 날짜로 무엇을해야하는지에 따라 달라집니다. 예를 들어 "n 일 전에 발생한 일"또는 "1972 년 1 월 1 일 이전에 발생한 일"이 실행 가능한지 또는 독자의 맥락에 적합한 지 여부에 따라 다릅니다.
wprl 2013 년

아마도 이벤트 목록을 "어제 ... 3 일 전 ... 10/5 월 ..."으로 보는 것은 혼란 스럽습니다. 나는 그것들이 언제 일어 났는지 사진을 얻기 위해 내 머릿속의 날짜로 변환해야한다. 날짜는 간결하고 정확하며, "시간 전"값은 대화 형이며 정밀도가 부족하며 일반적으로 관련 날짜에만 도움이됩니다. 나일 수도 있지만 아닐 수도 있습니다. :-)
RobG 2013 년

6
상황에 따라 다릅니다. 사실 어제라면 "2014 년 2 월 17 일에 낚시하러 갔다"라고 말하지 않을 것입니다. 거기에는 훨씬 더 많은 두뇌 정지가 있습니다. 이러한 종류의 텍스트는 최근 이벤트 목록에 적합합니다.
Simon Williams

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 Mine은 완전한 솔루션이 아니라 올바른 방향의 포인터 일뿐입니다. 나중에 업데이트 할 수 있도록 메모를 작성하거나 원하는 경우 자유롭게 답변을 편집 할 수 있습니다.
alex

date-fns도 살펴보세요 ! momentjs보다 풋 프린트가 훨씬 적기 때문에 코드베이스를 작게 유지하고 싶다면 훌륭한 라이브러리입니다!
mesqueeb

1
이 코드를 변경하여 트위터 스타일 getTimeAgo함수 gist.github.com/pomber/6195066a9258d1fb93bb59c206345b38
pomber

85

이 작업을 수행하는 날짜 라이브러리 인 moment.js를 작성 했습니다. 약 5KB (2011) 52KB (2019)이며 브라우저와 Node.js에서 작동합니다. 또한 JavaScript를위한 가장 인기 있고 유명한 날짜 라이브러리 일 것입니다.

timeago, 형식화, 구문 분석, 쿼리, 조작, i18n 등을 지원합니다.

과거 날짜에 대한 Timeago (상대 시간)는 moment().fromNow(). 예를 들어 2019 년 1 월 1 일을 timeago 형식으로 표시하려면 :

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

timeago 문자열은를 사용하여 사용자 정의 moment.updateLocale()할 수 있으므로 원하는대로 변경할 수 있습니다.

컷오프는 질문이 요청하는 것 ( "5 주"대 "1 개월")이 아니지만 어떤 문자열이 어떤 시간 범위에 사용되는지에 대해 문서화됩니다.


1
브라우저와 노드에서 작동하도록 만드는 것에 대한 명성 !!!!
wprl

48
그래도 그 크기 업데이트!
Askdesigners

1
date-fns도 살펴보세요 ! momentjs보다 풋 프린트가 훨씬 적기 때문에 코드베이스를 작게 유지하고 싶다면 훌륭한 라이브러리입니다!
mesqueeb

이 라이브러리는 좋은으로, 대답은 그것을 사용하는 인간 친화적 인 방식으로 숫자를 포맷하는 방법에 대한 설명이 포함되어 있지 않습니다
코드 속살

16

다음은 John Resig의 내용입니다-http: //ejohn.org/blog/javascript-pretty-date/

수정 ( 2014627 일) : Sumurai8 의 댓글에 대한 후속 조치 -링크 된 페이지는 여전히 작동하지만 pretty.js위의 기사에서 링크 된에 대한 발췌는 다음 과 같습니다.

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

용법:

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
안녕하세요 Floyd, 귀하의 답변에 몇 가지 변경 사항 (버그 수정, 개선 사항)을 추가했습니다.
괜찮 으시면 좋겠어요

잘 했어! 하지만 타임 스탬프 숫자 유형으로 작동하지 마십시오. if (typeof time == 'string') {time = time.replace (/-/ g, "/").replace(/[TZ]/와 같은 더 나은 필터가 필요할 수 있습니다. g, "")); }
아서 아라 우호

15

sugar.js 에는 훌륭한 날짜 형식 지정 기능이 있습니다.

뿐만 아니라 사용하기 편리한 문자열 서식, 숫자 서식 등과 같은 일반적인 범용 기능도 제공합니다.


1
동의합니다, sugar.js는 여기에서 더 많은 관심을받을 자격이 있습니다.
citykid

5

여기 설탕 대 순간의 예 : 주를 표시하는 달력의 경우 마지막 월요일 값이 필요했습니다.

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

나는 설탕을 훨씬 선호하고 moment.js를 몇 달 후에 이제 sugar.js로 전환합니다. 더 명확하고 Javascripts의 Date 클래스와 잘 통합됩니다.

OP 케이스는 두 라이브러리 모두에서 다루며 sugar.js의 경우 http://sugarjs.com/dates를 참조 하십시오.


4

이 js 스크립트는 매우 좋습니다. 당신이해야 할 일은 그것을 실행하는 것입니다. 모든 <time>태그는 상대 날짜로 변경되고 몇 분마다 업데이트되므로 상대 시간은 항상 최신 상태로 유지됩니다.

http://timeago.yarp.com/


1
이것이 최선의 해결책이라고 생각합니다. 라이브러리는 매우 적극적으로 유지 관리되며 Resig의 코드에서 영감을 얻었습니다. 매우 작고 현지화가 많고 통합하기가 쉽습니다.
John Bachir 2013

4

http://www.datejs.com/을 사용할 수있는 것 같습니다 .

그들은 당신이 설명하는 것을 정확하게 수행하는 메인 페이지에 예제가 있습니다!

편집 : 사실, 나는 내 머리에서 당신의 질문을 뒤집 었다고 생각합니다. 어쨌든 정말 대단한 도서관이기 때문에 꼭 확인하실 수있을 것 같아요!

x2 편집 : 다른 사람들이 http://momentjs.com/ 이 현재 사용 가능한 최선의 선택 이라고 말한 것을 반영하겠습니다 .

x3 편집 : 1 년 넘게 date.js를 사용하지 않았습니다. 나는 모든 데이트 관련 요구에 대해 momentjs를 독점적으로 사용하고 있습니다.


좋은 lib 제안. 국제화는 확실히 플러스입니다.
Stephen

Date.js도 내 첫 번째 생각 이었지만, 문서 어딘가에 숨겨져있을 수 있지만 숫자에서 형식으로 이동할 수있는 방법은 없습니다.
rampion

Date.js는 심각한 버그가있는 것으로 알려져 있으며 프로덕션 환경에서 신뢰할 수 없습니다. 많은 프레임 워크가 Date.js에서 Moment.js로 전환되고 있습니다
John Zabroski 2013 년

나는 datejs가 :( 리눅스에서 작동하지 않는 하드 방법을 배웠
지방 fantasma
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.