2019/07/02更新

[Javascript] Moment.jsを使って日付を扱おう

このエントリーをはてなブックマークに追加      

こんにちは、@yoheiMuneです。
JavaScriptで日付を扱う場合に、デフォルトではDateクラスくらいしかなくて使いづらい。その問題を解消するライブラリはいくつか存在しますが、その中でMoment.jsが非常に使いやすいので、今日はその使い方をブログに書きたいと思います。



目次




はじめに

本記事は、moment.jsを用いた日付処理について記述しています。ライブラリを用いない日付処理については「[JavaScript] 今日、明日、昨日、月末、月初などを取得する」でブログを書いたので、もし良ければご参考ください。



Moment.jsとは

Moment.jsは、Javascriptで日付を扱うためのライブラリです。文字列からパースしたり、月末月初を求める演算ができたり、任意のフォーマットで出力できたり、と様々な機能があります。日付の演算やパース処理をする際には、必ず使いたいライブラリです。

このブログではv.2.20.1を対象に執筆しています。最新のバージョンは公式ページでご確認ください。


インストール

インストール手順はnpmbrowserifyなど様々な方法が用意されていますが、CDNで公開されているものを使うとすぐに導入できます。
<!-- CDNから読み込む. -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.20.1/moment.min.js" type="text/javascript"></script>



基本的な使い方

ここからはMoment.jsの使い方を説明します。

インスタンスの作成

Moment.jsのインスタンスを作成する方法は、いくつか存在します。
// 現在日時から作成する.
moment()
// 日付文字列から作成する.
// 日付のフォーマットは、リンク先を参照のこと.
// https://momentjs.com/docs/#/parsing/string-format/
moment('2018-01-23', 'YYYY-MM-DD')
moment('2018-01-23T12:34:56+0900', 'YYYY-MM-DDTHH:mm:ssZ')
moment("2018-01-01T05:06:07", moment.ISO_8601)

// 複数のフォーマットを指定することもできる.
moment('2018-01-23', ['YYYY-MM-DD', 'YYYY/MM/DD'])
moment('2018/01/23', ['YYYY-MM-DD', 'YYYY/MM/DD'])
日付文字列からパースする処理は非常に便利です。この要件があればぜひMoment.jsを使いたいところです。
// オブジェクト指定ですることもできます.
// https://momentjs.com/docs/#/parsing/object/
moment({
    year       : 2018,
    month      : 3,
    day        : 5,
    hour       : 15,
    minute     : 10,
    second     : 3,
    millsecond : 100
})
// Timestamp(ミリ秒)から
var timestamp = new Date().getTime()
moment(timestamp)

// Timestamp(秒)から
var timestamp = new Date().getTime() / 1000
moment.unix(timestamp)
// JavascriptのDateオブジェクトから
moment(new Date())
// 配列で指定(年、月、日、時、分、秒、ミリ秒)
moment([ 2018, 1, 12, 23, 59, 59, 125])
// 別のMoment.jsのインスタンスからコピー
var m1 = moment()
var m2 = moment(m1)

バリデーション

作成したインスタンスが正しい状態であるか、バリデーションで確認できます。
// バリデーション
moment('2018-01-23', 'YYYY-MM-DD').isValid()  // true
moment('invalid date').isValid()              // false



値の取得と更新

Moment.jsのインスタンスから値を取得したり、値を設定したりする方法です。

値のGet

Momentのインスタンスから値を取得するには、以下のように行います。
// get関数を使う.
moment().get('millisecond')
moment().get('second')
moment().get('minute')
moment().get('hour')
moment().get('date')
moment().get('day')  // 曜日
moment().get('month')
moment().get('year')

// 各関数を使う.
moment().millisecond()
moment().second()
moment().minute()
moment().hours()
moment().date()
moment().day()  // 曜日
moment().month()
moment().year()

値のSet

Momentに値を設定するには、以下のように行います。
// set関数を使う.
moment().set('millisecond', 123);
moment().set('second', 30);
moment().set('minute', 20);
moment().set('hour', 13);
moment().set('day', 0);     // 0:日曜日、6:土曜日
moment().set('date', 1);
moment().set('month', 3);   // 「0」始まり
moment().set('year', 2013);

// オブジェクト形式でまとめてセットもできる.
moment().set({'year': 2013, 'month': 3});

// 各関数を使う.
moment().millisecond(100)
moment().second(10)
moment().minute(20)
moment().hours(5)
moment().date(12)
moment().day(0)
moment().month(1)
moment().year(2017)



値の演算

Moment.jsでは、日付の足し算/引き算などの演算を行うことができます。この機能は非常に便利です。

値の足し算/引き算

日付に対して、足したり引いたりできます。
// 足し算.
// https://momentjs.com/docs/#/manipulating/add/
moment().add(360, 'days')

// 複数まとめて足し算.
moment().add({ days : 7, months : 1 })
// 引き算.
moment().subtract(360, 'days')
moment().subtract({ days : 7, months : 1 })

// add関数の引数にマイナスを指定してもOK.
moment().add(-360, 'days')
また、月の演算の場合には月末考慮が行われます。
moment([2018, 0, 31]);                  // 1/31
moment([2018, 0, 31]).add(1, 'months'); // 2/28

Start of Time

年始めや月初を簡単に作成できます。
moment().startOf('year');    // 年始。時分秒は00:00:00。
moment().startOf('month');   // 月初。時分秒は00:00:00。
moment().startOf('week');    // 週始め(日曜日始まり)。時分秒は00:00:00。
moment().startOf('day');     // 本日。時分秒は00:00:00。
moment().startOf('date');    // 本日。時分秒は00:00:00。
moment().startOf('hour');    // 本日の現在hour。分秒は00:00。
moment().startOf('minute');  // 本日の現在hour/minute。秒は00。
moment().startOf('second');  // 本日の現在hour/minute/second。ミリ秒は000。

End of Time

年末や月末を簡単に計算できます。
moment().endOf('year');    // 年始。時分秒は23:59:59。
moment().endOf('month');   // 月初。時分秒は23:59:59。
moment().endOf('week');    // 週始め(日曜日始まり)。時分秒は23:59:59。
moment().endOf('day');     // 本日。時分秒は23:59:59。
moment().endOf('date');    // 本日。時分秒は23:59:59。
moment().endOf('hour');    // 本日の現在hour。分秒は23:59。
moment().endOf('minute');  // 本日の現在hour/minute。秒は59。
moment().endOf('second');  // 本日の現在hour/minute/second。ミリ秒は999。

2つの日付の差

2つの日付の差を計算することもできます。
// 差を計算
var a = moment([2018, 0, 29]);
var b = moment([2018, 0, 28]);
a.diff(b)         // 86400000 ms
a.diff(b, 'days') // 1

// デフォルトの振る舞いは切り捨てだが、float値で取得することもできる。
var a = moment([2018, 9]);
var b = moment([2017, 0]);
a.diff(b, 'years');       // 1
a.diff(b, 'years', true); // 1.75

月の日数

指定月の日数を取得することができます。
// Days in Month.
moment("2019-02", "YYYY-MM").daysInMonth(); // 28
moment("2020-02", "YYYY-MM").daysInMonth(); // 29 (うるう年)



フォーマット

任意の形式で日付文字列を作成できます。
// 日付文字列にフォーマットする.
// https://momentjs.com/docs/#/displaying/format/
moment().format()                       // "2018-01-23T10:05:55+09:00" (ISO8601)
moment().format("YYYY-MM-DD HH:mm:SS")  // 2018-01-30 10:58:05



日付の比較

2つのインスタンスで、比較を行うことができます。

ドキュメント


等価チェック(Is Same)

moment('2018-10-20').isSame('2018-10-20'); // true

// 比較対象を絞ることもできる.
moment('2018-10-20').isSame('2018-01-01', 'year');   // 年で比較。true
moment('2018-10-20').isSame('2018-10-21', 'month');  // 年月で比較。true
moment('2018-10-20').isSame('2018-10-20', 'day');    // 年月日で比較。true

より小さい(Is Before)

moment('2018-10-20').isBefore('2018-10-21'); // true

moment('2018-10-20').isBefore('2018-12-31', 'year'); // 年で比較。false
moment('2018-10-20').isBefore('2019-01-01', 'year'); // 年で比較。true

より大きい(Is After)

moment('2018-10-20').isAfter('2018-10-19'); // true
moment('2018-10-20').isAfter('2018-01-01', 'year'); // 年で比較。false
moment('2018-10-20').isAfter('2017-12-31', 'year'); // 年で比較。true

以下(Is Same or Before)

moment('2018-10-20').isSameOrBefore('2018-10-21');  // true
moment('2018-10-20').isSameOrBefore('2018-10-20');  // true
moment('2018-10-20').isSameOrBefore('2018-10-19');  // false

moment('2018-10-20').isSameOrBefore('2017-12-31', 'year'); // 年で比較。false
moment('2018-10-20').isSameOrBefore('2018-12-31', 'year'); // 年で比較。true
moment('2018-10-20').isSameOrBefore('2019-01-01', 'year'); // 年で比較。true

以上(Is Same or After)

moment('2018-10-20').isSameOrAfter('2018-10-19'); // true
moment('2018-10-20').isSameOrAfter('2018-10-20'); // true
moment('2018-10-20').isSameOrAfter('2018-10-21'); // false

moment('2018-10-20').isSameOrAfter('2019-12-31', 'year'); // false
moment('2018-10-20').isSameOrAfter('2018-01-01', 'year'); // true
moment('2018-10-20').isSameOrAfter('2017-12-31', 'year'); // true



Locale対応

ロケール設定を追加で読み込むことで、日本語表現を扱うこともできます。
<!-- 日本語表現を扱いたい場合には、以下も追加で読み込む -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.20.1/locale/ja.js" type="text/javascript"></script>
// 表示.
moment().format("YYYY-MM-DD(dddd)") // 2018-01-30(火曜日)

// パース.
moment('2018-01-30(火曜日)', 'YYYY-MM-DD(dddd)')



最後に

Moment.jsは今でもかなり利用されているライブラリで、非常に強力で便利です。このブログのように一度全体的に学んでおくと、今後の引き出しになるので定期的にやってます。この記事が何か参考になれば嬉しいです。

最後になりますが本ブログでは、フロントエンド、Node.js、Linux、Java、Python、インフラ、Swift、Go言語、機械学習、などの技術トピックを発信をしていきます。「プログラミングで困ったその時に、解決の糸口を見つけられる」そんな目標でブログを書き続けています。今後も役立つネタを書いていきますので、ぜひ本ブログのRSSTwitterをフォローして貰えたら嬉しいです ^ ^

最後までご覧頂きましてありがとうございました!





こんな記事もいかがですか?

RSS画像

もしご興味をお持ち頂けましたら、ぜひRSSへの登録をお願い致します。