_.niceDate・・・日付データを与えて「〜分前」を簡単に実装するunderscore.js 拡張
underscore.js は、誰かが「ビルトイン拡張しないPrototype.jsだ」って言っていました。実際、そうだと思います。
window._ に、いろいろユーティリティが詰まってるんです。(「 _ 」じゃなくも、できる)
// 配列が空かどうかしらべたい _.isEmpty([]) // true _([]).isEmpty() // true。同じことをしてる。ちょっとjQueryぽい
で、underscore.js は、jQuery みたいに拡張できます。プラグインが作れるんです。
// jQueryなら $.fn.newPlugin = function () {...}; // underscore.js なら _.mixin({ myUtil: function () {...} });
documentはこれです→ _.mixin
で、これ流行りますかね? underscore.js を拡張するやつ。
流行らないかも知れません。ほとんどの場合、拡張したところで、ただの関数だからです。
でも、サーバ用とかで、あれば便利なちょっとしたものはあるんじゃないでしょうか。
そういうものが、「_ 」に集まるのはいいことだと思います。
これ↓は自分用につくってみました。_.niceDate() という関数がつかえるように、拡張してます。よければ、使ってみてください。
// depends on underscore.js /** * @param {String|Number|Date} date * @param {String=} lang 'ja' or 'en'. default is 'ja' * @return {String} */ _.mixin({ niceDate: (function(date, lang) { var DAY, HOUR, MINUTE, MONTH, SECOND, WEEK, YEAR, dateFormat, formatize, langs, pluralize; SECOND = 1000; MINUTE = 60 * SECOND; HOUR = 60 * MINUTE; DAY = 24 * HOUR; WEEK = 7 * DAY; MONTH = 31 * DAY; YEAR = 365 * DAY; langs = { en: { AGO: ' ago', AFTER: ' after', SECOND: ' second', MINUTE: ' minute', HOUR: ' hour', DAY: ' day', WEEK: ' week', MONTH: ' month', YEAR: ' year', PLURAL: 's' }, ja: { AGO: '前', AFTER: '後', SECOND: '秒', MINUTE: '分', HOUR: '時間', DAY: '日', WEEK: '週', MONTH: '月', YEAR: '年' } }; dateFormat = { en: { HOUR_MINUTE: "%_:%_", MONTH_DATE: "%_.%_", YEAR_MONTH_DATE: "%_.%_.%_" }, ja: { HOUR_MINUTE: "%_:%_", MONTH_DATE: ["%_", langs.ja.MONTH, "%_", langs.ja.DAY].join(''), YEAR_MONTH_DATE: ["%_", langs.ja.YEAR, "%_", langs.ja.MONTH, "%_", langs.ja.DAY].join('') } }; pluralize = function(num, str, lang) { num = Math.floor(num); if (lang.PLURAL && num > 1) { return num + str + lang.PLURAL; } else { return num + str; } }; formatize = function() { var format, value, values, _i, _len; format = arguments[0], values = 2 <= arguments.length ? __slice.call(arguments, 1) : []; for (_i = 0, _len = values.length; _i < _len; _i++) { value = values[_i]; format = format.replace("%_", value); } return format; }; return function(date, lang_) { var agoOrLater, dist, fmt, now; if (_.isString(date) || _.isNumber(date)) { date = new Date(date); } if (_.isDate(date)) { now = new Date().getTime(); lang_ = _.isString(lang_) && langs[lang_] ? lang_ : "ja"; lang = langs[lang_]; fmt = dateFormat[lang_]; dist = now - date.getTime(); agoOrLater = dist > 0 ? lang.AGO : lang.AFTER; dist = Math.abs(dist); if (dist < MINUTE) { return "" + (pluralize(dist / SECOND, lang.SECOND, lang)) + agoOrLater; } else if (dist < HOUR) { return "" + (pluralize(dist / MINUTE, lang.MINUTE, lang)) + agoOrLater; } else if (dist < DAY) { return "" + (pluralize(dist / HOUR, lang.HOUR, lang)) + agoOrLater; } else if (dist < DAY * 3) { return "" + (pluralize(dist / DAY, lang.DAY, lang)) + agoOrLater; } else if (dist < YEAR) { return "" + (formatize(fmt.MONTH_DATE, date.getMonth() + 1, date.getDate())); } else { return "" + (formatize(fmt.YEAR_MONTH_DATE, date.getFullYear(), date.getMonth() + 1, date.getDate())); } } }; })() });
つかうとき:
// date フォーマットの文字列から var string = "Sat Nov 05 14:25:39 +0000 2011"; _.niceDate(string); // "2時間前" _.niceDate(string, 'en'); // "2 hours ago" // time フォーマットの数値から var number = new Date().getTime() + 3 * 1000; _.niceDate(number); // 3秒後 // dateオブジェクトから var date = new Date(new Date().getTime() - 2 * 24 * 60 * 60 * 1000); _.niceDate(date); // 2日前