アシアルブログ

アシアルの中の人が技術と想いのたけをつづるブログです

JavaScriptで日付を扱うならこれ!「moment.js」

こんちは。松田です。
JavaScriptで日付を扱う場合、通常はDateオブジェクトを使いますが、これが使いづらい上に機能が足りてないのでいろいろ苦労しますよね。

そこでオススメなのがmoment.jsです。
これを使えば日付処理の悩みが解消されること間違いナシです。

以下の内容は5月15日時点、バージョン2.0.0の情報を元に記述しています。

■ インストール



http://momentjs.com/ からダウンロード、

もしくは、



npm install moment



 

■ つかいかた(基礎編)


ダウンロードしたmoment.jsをscriptタグで読み込ませたら準備完了です。
あとは下記のような実装で使用できます。


// momentオブジェクトを初期化して・・・
var m = moment();

// formatで出力!
var output = m.format("YYYY年MM月DD日 HH:mm:ss dddd");
 
console.log(output);  // => 2013年05月15日 12:34:56 Wednesday




■ 初期化方法いろいろ


momentオブジェクトには多くの初期化方法が用意されています。
特に第二引数で入力値のフォーマットを指定する機能のおかげで、どんな日付フォーマットからでも柔軟にオブジェクトを生成することができるようになっています。



// 現在時刻
moment();

// ミリ秒で指定
moment(1368543600000); 

// タイムスタンプ(秒)で指定
moment.unix(1368543600);

// Date.parseで解析可能な文字列を指定
moment("May 15, 2013");

// Dateオブジェクトから初期化
moment(new Date(2013, 4, 15));

// 配列から初期化
moment([2013, 4, 15]); // ※monthは-1した値を指定

// 別のmomentオブジェクトから初期化
moment(moment([2013, 4, 15]));


// 第二引数で入力値フォーマットを指定して初期化
moment("05-15-2013", "DD-MM-YYYY");
moment("20130515", "YYYYMMDD");
moment("2013年05月15日", "YYYY年MM月DD日"); // 実は"YYYYMMDD"だけでも通る
moment(1368543600 + "", "X"); 


※フォーマットに使用出来る文字列に関してはDocsの#String+Formatの欄を参照してください。


■ 出力方法あれこれ




var m = moment();

// formatを指定して出力
m.format("YYYY年MM月DD日 ddd");

// 各単位のメソッド
m.year();    // 年
m.month();   // 月 ※ 0〜11の値!
m.date();   // 日
m.day();    // 曜日
m.hours();    // 時
m.minutes();  // 分
m.seconds();  // 秒
m.milliseconds();  // ミリ秒

各単位ごとのメソッドはgetterとしてもsetterとしても使用できます。
引数を渡せばsetter、引数が無ければgetterです。

また、例によってmonthだけは0〜11の値を扱います。
m.month(4)をsetすれば5月のmomentオブジェクトになりますが、
その後m.month()をgetするとやっぱり4が返ってきます。
Dateでもみんなを悩ませたこの仕様は何が目的なんでしょうね。


var m = moment("2013-01-01", "YYYYMMDD");
m.month(); // => 0
m.month(10).format("YYYY-MM-DD"); // => 2013-11-01





■ つかいかた(応用編)


メソッドの説明をちまちま書くよりも実例をいくつか挙げたほうが分かりやすそうなので、
実装例をいくつか挙げてみます。


○ 曜日を日本語で出力したい


moment.jsは多言語対応しているので日本語のlangを設定して出力させます。
langのデフォルト値は 'en' です。


// lang:jaを登録。これ以降はlangを指定しなくても自動的にjaが使用される。
moment.lang('ja', {
    weekdays: ["日曜日","月曜日","火曜日","水曜日","木曜日","金曜日","土曜日"],
    weekdaysShort: ["日","月","火","水","木","金","土"],
});

// moment生成して・・・
var m = moment("May 15, 2013");

// 日本語で出力
m.format("MM/DD (ddd) dddd"); // => 05/15 (水) 水曜日 

// でもやっぱり英語で出力
m.lang("en").format("MM/DD (ddd) dddd"); // => 05/15 (Wed) Wednesday



○ 今月1日の曜日を数値で




// dayメソッドが「曜日」(0〜6)でdateメソッドが「日」(1〜31)なので注意!
moment().date(1).day(); // => 3  (水曜日)



○ 今週の月曜日、正午キッチリのタイムスタンプがほしい




moment()
	.day(1)     // dayで曜日指定. 0:日曜 〜 6:土曜
	.hours(12)  // 12時を指定
	.minutes(0).seconds(0).milliseconds(0) // これを指定しないと現在時刻の分,秒が使用される
	.format("X"); // => 1368414000



○ 指定した日付が存在するか確認




moment("2013-02-29", "YYYY-MM-DD").isValid(); // => false



○ 今日から30日後の日付が欲しい




moment().add("days", 30).format("YYYY年MM月DD日"); // => 2013年06月14日 



○ 今月って何日まであったっけ?




moment().daysInMonth() // => 31



○ 4月1日から今日まで何日あった?




moment().diff(moment([2013, 3, 1]), "days"); // => 44



○ 日付Aが日付Bよりも後の日付かチェック




var momentA = moment([2013, 3, 1]);
var momentB = moment([2013, 5, 1]);
momentA.isAfter(momentB); // => false



○ momentオブジェクトのclone生成




var baseMoment = moment();
var cloneMoment = baseMoment.clone();



開発上特に役に立ちそうな機能を挙げましたが、まだまだ多くの機能がmoment.jsには実装されています。
JavaScriptで日付を扱うならとりあえず入れておいて損はないんじゃないんでしょうか。

その他すべての機能はDocsを参考にどうぞ!



■ その他


format()で月の日数(daysInMonth)を表示する方法が知りたい!
できないのかなー