はじめに
JavaScriptで日付や時刻を扱おうとして、Dateオブジェクトの扱いにくさに手を焼いた経験はないでしょうか。タイムゾーンの計算、フォーマットの調整、相対時間の表示……これらを標準APIだけでこなすのは、想像以上に骨が折れます。
そんな悩みを長年解決してきたのが、日付操作ライブラリのMomentです。直感的なメソッドチェーンで日付を自在に操れることから、一時期はほぼすべてのJavaScriptプロジェクトで見かける定番ライブラリでした。
ただし、この記事で紹介するMomentには少し特殊な立ち位置があります。開発チームは2020年に「新規プロジェクトでの利用を推奨しない」というメンテナンスモード宣言を出しており、現在は新機能開発を凍結した状態で保守されています。既存プロジェクトでの利用や、レガシーコードの保守でMomentに触れる方に向けて、特徴と使い方、そして開発終了に至った背景まで解説します。
とはいえ、まずは実際にどう動くのか触ってみるのが早いと思います。先に挙動を見たい方はこちらからどうぞ。
Momentとは
Momentは、JavaScriptにおける日付・時刻の解析・検証・操作・表示を簡単にするためのライブラリです。2011年に公開されて以来、npmでのダウンロード数が週1,000万を超えるほど広く使われてきました。標準のDateオブジェクトをラップし、メソッドチェーンで直感的に日付を扱えるAPIを提供します。
主な特徴
- 豊富なフォーマット指定 -
format()にトークン文字列を渡すだけで、任意の表示形式に変換できる - 柔軟な日付演算 -
add()やsubtract()で加減算、diff()で差分計算が簡単に書ける - 多言語ロケール対応 - 100以上のロケールが用意されており、
locale()で表示言語を切り替えられる - 相対時間表示 -
fromNow()で「3時間前」のような相対的な表現を自動生成できる
一方で、Momentにはミュータブル(破壊的な変更を行う)な設計や、バンドルサイズの大きさといった弱点も指摘されてきました。これらの課題を解決するために生まれたのが、イミュータブルかつツリーシェイキング可能な設計を持つdate-fnsのような後発ライブラリです。開発チーム自身も公式ドキュメントで、新規プロジェクトにはdate-fnsやLuxon、Day.jsといった代替ライブラリの検討を推奨しています。
インストール
npmを使う場合は、以下のコマンドでインストールできます。
npm install moment
Yarnの場合は次のとおりです。
yarn add moment
CDN経由で読み込む場合は、<script>タグでも利用できます。
<script src="https://cdn.jsdelivr.net/npm/moment@2.30.1/moment.min.js"></script>
Momentのサンプルを動かす
以下はmoment()で現在時刻を取得し、format()で表示形式を変え、add()で日付を加算する例です。日付を入力すると、その日から何日後か・何日前かをリアルタイムに計算して表示します。日付を書き換えたり、加算日数を変えたりして挙動を確かめてみてください。
要点だけを抜き出すと、次のようなコードになります。
import moment from 'moment'
const now = moment()
now.format('YYYY年MM月DD日 HH:mm:ss') // 任意の書式で出力
now.add(7, 'days') // 7日後を計算(破壊的変更)
now.subtract(1, 'month') // 1か月前を計算
now.fromNow() // "3時間前" のような相対表示
now.isBefore('2027-01-01') // 日付の比較
実際に動かせるサンプルは以下です。
このサンプルでは、clone()を使って元のmomentオブジェクトを複製してからadd()しています。Momentのインスタンスはミュータブル(破壊的)なため、clone()を挟まずにadd()を呼ぶと元の日付そのものが書き換わってしまう点に注意してください。加算日数をマイナスの値にすればsubtract()と同じ結果になり、過去の日付を計算できます。
基本的な使い方
もっとも基本的な使い方は、moment()で現在時刻のインスタンスを生成し、format()で文字列に変換する流れです。
import moment from 'moment'
// 現在時刻の取得とフォーマット
const now = moment()
console.log(now.format('YYYY-MM-DD HH:mm:ss'))
// 文字列から日付をパース
const parsed = moment('2026-08-05', 'YYYY-MM-DD')
console.log(parsed.isValid()) // true
// 日付の加算・減算
const nextWeek = moment().add(1, 'week')
const lastMonth = moment().subtract(1, 'month')
// 日付同士の比較
console.log(moment('2026-01-01').isBefore('2026-12-31')) // true
format()に渡すトークンはYYYY(西暦4桁)、MM(月2桁)、DD(日2桁)、HH:mm:ss(時分秒)のように組み合わせることで、任意の表示形式を作れます。
実践的なユースケース
相対時間の表示
投稿日時やコメントの表示で「3時間前」「2日前」のような相対時間を出したい場面は多くあります。MomentのfromNow()を使えば、対象の日時と現在時刻との差分を自動で言語化してくれます。
分数を大きくしていくと、fromNow()の表示が「数分前」から「1時間前」「1日前」へと自動的に単位を切り替えていく様子が確認できます。この単位変換ロジックを自前で実装する手間が省けるのが、Momentが長く支持されてきた理由のひとつです。
日付範囲のバリデーション
予約フォームやイベント登録フォームでは、開始日と終了日の前後関係をチェックする場面がよくあります。isBefore()やisAfter()、diff()を組み合わせることで、こうした日付範囲の検証をシンプルに書けます。
終了日を開始日より前に設定するとisBefore()がtrueを返し、エラーメッセージに切り替わります。diff()の第2引数に'days'ではなく'months'や'hours'を渡せば、それぞれの単位での差分に変えられます。
まとめ
Momentは、日付操作という地味ながら誰もがつまずくテーマを、直感的なAPIで解決してきたライブラリです。format()によるフォーマット、add()/subtract()による演算、fromNow()による相対時間表示など、日付にまつわる面倒な処理を一通りカバーしています。
一方で、開発チームが公式にメンテナンスモードを宣言している点は見過ごせません。既存プロジェクトの保守で使う分には問題ありませんが、新規プロジェクトを始める場合はdate-fnsやDay.js、Luxonといった後継候補も含めて比較検討することをおすすめします。まずは今回のサンプルを書き換えながら、MomentのAPIがどれだけ直感的かを体感してみてください。