人間が使いやすい相対日付形式のJavaScriptライブラリ[終了]


94

現在の日付を基準にして、いくつかの日付を人にわかりやすい形式で表示したいと思います。

人に優しい相対日付の例:

  • 10秒前
  • 今から20分
  • 1日前
  • 5週間前
  • 2ヶ月前

基本的には、最高の桁数を忠実に維持します(優先的には、これらの単位の2つを渡すときにのみ単位をシフトアップします-1か月ではなく5週間)。

私は、次のような制御が少なく、より友好的な日付を持つライブラリーと一緒に暮らすことができますが:

  • 昨日
  • 明日
  • 先週
  • 数分前に
  • 数時間で

このための人気のあるライブラリはありますか?


単に実際の日付と時刻を提示するよりも、「1日前」の方が「人に優しい」のはなぜですか。
RobG 2012

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 2012

@mmaclaurin Mineが完全なソリューションになることは決してなく、正しい方向への指針にすぎません。後で更新するようにメモします。必要に応じて、回答を自由に編集してください。
アレックス

date-fnsもご覧ください。コードベースを小さくしたい場合は、momentjsよりもはるかに小さいフットプリントであるため、これは素晴らしいライブラリです!
mesqueeb 2017年

1
私はTwitterのスタイルにするためにこのコードを変更するgetTimeAgo機能gist.github.com/pomber/6195066a9258d1fb93bb59c206345b38を
pomber

85

これを行う日付ライブラリであるmoment.jsを書きました。それは約5KB(2011) 52KB(2019)であり、ブラウザーとノードで動作します。また、おそらく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 2013年

48
でも、そのサイズは更新されます!
Askdesigners 2016年

1
date-fnsもご覧ください。コードベースを小さくしたい場合は、momentjsよりもはるかに小さいフットプリントであるため、これは素晴らしいライブラリです!
mesqueeb 2017年

このライブラリであり、答えはそれを用いてヒトに優しい方法で番号をフォーマットする方法についての説明が含まれていないとして良いとして
コードのささやき

16

John Resigからの抜粋-http ://ejohn.org/blog/javascript-pretty-date/

EDIT(2014年6月27日):からのコメントにフォローアップ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
こんにちはフロイド、私はあなたの答えにいくつかの変更(バグ修正、改善)を追加しました。あなたが気にしないことを願って..
ファイズ

いいね!しかし、タイムスタンプ数値タイプでは機能しません。おそらくif(typeof time == 'string'){time = time.replace(/-/ g、 "/").replace(/[TZ]/ g、 "")); }
ArthurAraújo16年

15

sugar.jsには優れた日付フォーマット機能があります。

それだけでなく、文字列のフォーマット、数値のフォーマットなど、便利な一般的な汎用機能も提供します。


1
ここで、sugar.jsはもっと注目に値します。
シティキッド

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に切り替えます。それはより明確であり、JavaScriptの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提案。国際化は間違いなくプラスです。
スティーブン、

Date.jsも私が最初に考えたものですが、数値から形式に変換する方法がありません。ドキュメントのどこかに隠されている可能性があります。
2011年

Date.jsには重大なバグがあることが知られており、本番環境では信頼できません。多くのフレームワークがDate.jsからMoment.jsに切り替わります
John Zabroski 2013

Linuxでdatejsが機能しないという難しい方法を学びました:(
fat fantasma
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.