現役エンジニアが教える!実践JavaScript入門 〜日付操作〜
今回扱う内容:日付操作
開発でよく使われる日付操作の、基本操作や便利なライブラリを習得しよう。
日付操作の基本
JavaScriptで日付操作をするにはDateオブジェクトを使います。
詳しいDateオブジェクトの説明や使えるメソッドに関してはMDNの記事を参考にしてみてください。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Date
Dateオブジェクトの生成
Dateオブジェクトの使い方としては、はじめに次のように記述することでコンストラクタを呼び出し、Dateオブジェクトを生成します。
この際に、引数に空を渡すことで現在時刻のDateオブジェクトを生成できます。
const date = new Date();
引数には次のような日時を渡すことができ、それぞれ指定された日時でのDateオブジェクトを生成できます。
この時の1つ目のポイントは、引数に数字を渡す場合月は0起点で始まるということです。そのため、例に示す11は12月を表します。
2つ目のポイントは後に説明するUNIX時間という時間表現をコンストラクタの引数に渡すことができることです。
new Date("December 17, 1995 03:24:00");
new Date("1995-1217T03:24:00");
new Date(1995,11,17); // 11->12月を表す
new Date(628021800000); // UNIX時間
年月日や時刻の取得
生成したDateオブジェクトに次のようなメソッドを使うことで年月日や時刻の取得ができます。またここでもgetMonth
メソッドから取得できる月は0起点で始まることに注意しましょう。
const date = new Date();
date.getMonth(); // 月
date.getDate(); // 日
date.getFullYear(); // 年
date.getHours(); // 時刻
date.getMinutes(); // 分
date.getSeconds(); // 秒
経過時間の計算(ミリ秒)
何らかの操作にかかった時間など、経過時間を取得したい場合に使えるDate.now
メソッドを使った計算方法をここでは紹介します。このメソッドはDateオブジェクトを生成せずに呼び出すことができる静的メソッドです。また、Date.now
メソッドはUTC(協定世界時)での1970年1月1日の0時0分0秒から現在までの経過時間をミリ秒単位で返します。そのため経過時間を取得する際には次のように操作の開始と終わりにメソッドを呼び、その差分をとることでミリ秒単位での経過時間を取得します。
const start = Date.now(); // 例:1660990955721
const end = Date.now(); // 例:1660990988021
const elapsed = end - start; // 例:32300
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Date/now
UNIX時間の取得
UNIXではUTC(協定世界時)1970年1月1日の0時0分0秒が元期と定められており、UNIX時間はこの元期からの秒数を表します。先ほどのDate.now
メソッドでの単位はミリ秒であり、UNIX時間の単位は秒であるのでUNIX時間として取得する際には次のように変換する必要があります。
const seconds = Math.floor(Date.now()/1000);
主要な日付操作ライブラリ
前節ではDateオブジェクトを使った簡単な日付操作を紹介しましたが、ここでは日付操作の主要なライブラリを3つご紹介します。ライブラリを使うことでシンプルにコードが書けるので、複雑な処理にはライブラリの使用をおすすめします。
Moment.js
Moment.jsは昔からあり、既存のWebサービス内で一番使われている日付操作ライブラリです。昔からあるということから実装が古いという面もあり、現在はレガシーなプロジェクトとしてメンテナンスモードで提供されています。
なのでMoment.jsは新しい開発での使用は推奨されておらず、この後紹介するライブラリを使うことをお勧めします。
ですがMoment.jsに依存したライブラリも多数あるのでそうしたライブラリを使う際や、既存のサービスの改修をする際には新しいライブラリに移行するコストもかかるので、まだまだ使う場面はあります。
そのためMoment.jsの使い方を見ていきましょう。
今回は簡略化のためnpmや、yarnなどのパッケージマネージャーから使うのではなくcdnから使用します。
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.20.1/moment.min.js"></script>
これより、Moment.jsのメソッドを使うことができます。使い方のサンプルコードは次のようになります。
substract
メソッドは引数で渡した期間から時刻を引く、日時の減算をします。このようにMoment.jsを使うとチェーンメソッドでシンプルに日付処理を行うことができます。
moment(); // 現在時刻のmomentオブジェクトを生成
moment("2019-01-25").format("MM/DD/YYYY"); // momentオブジェクトの時刻をMM/DD/yyyyに成形
moment().subtract(7, "year").format("MM/DD/YYYY"); // 現在2022年から7年引く -> 08/20/2015
date-fns
date-fnsはMoment.js以降、比較的新しい人気の日付操作ライブラリです。特徴としては日付操作をオブジェクトではなく関数を使用して行います。豊富な関数が用意されているのでぜひ公式のドキュメントを参照してみてください。
ここでは簡単な使い方についてみていきます。
まず初めにdate-fnsの導入方法ですが、1系のバージョンのものはScriptタグのCDNからインポートできます。
<script src="https://cdnjs.cloudflare.com/ajax/libs/date-fns/1.30.1/date_fns.js"></script>
2系以降では、パッケージマネージャ以外の導入方法としてES Moduleを使うことができます。具体的には、JavaScriptファイルに次のように記述します。
import {format, parseIOS, subYears} from "https://esm.run/date-fns";
JavaScript内で使用する際には上記のものを記述すれば十分ですが、動画同様Chromeのデベロッパーツールで読み込む際にはこちらを記述します。
const {format, parseISO, subYears} = await import ("https://esm.run/date-fns");
これでdate-fnsの導入はでき、format, parseISO, subYearsメソッドを使うことができます。使い方のサンプルコードは次のようになります。parseISOメソッドは文字列をDate型に変換するメソッドです。また2行目はMoment.jsでも行った日時の減算をdate-fnsでも実行します。
format(parseISO("2019-01-25"), "MM/DD/YYYY"); // 01/25/2019
format(subYears(new Date(), 7), "MM/DD/YYYY"); // 08/20/2015
Day.js
Day.jsもMoment.js以降、比較的新しい人気の日付操作ライブラリです。特徴としてはMoment.jsとほぼ同じ使い方で利用でき、軽量でシンプルという点が挙げられます。
導入方法もMoment.jsと同様に次のように記述します。
<script src="https://cdnjs.cloudflare.com/ajax/libs/dayjs/1.11.4/dayjs.min.js"></script>
使い方のサンプルコードは次のようになります。
使い方もMoment.jsとよくにていることがわかります。
dayjs(); // 現在時刻のdayjsオブジェクトを生成
dayjs("2019-01-25").format("MM/DD/YYYY"); // dayjsオブジェクトの時刻をMM/DD/yyyyに成形
dayjs().subtract(7, "year").format("MM/DD/YYYY"); // 08/20/2015
Moment.jsとDay.jsの違い
Moment.jsとDay.jsの違いは、Moment.jsは**オブジェクトが変更可能(mutable)であり、Day.jsはオブジェクトが変更不可(immutable)**である、という点です。これは次のようにnow
という変数に現在時刻のオブジェクトを生成し、日時の減算をした後でのnow
の変化をそれぞれ見ていきます。するとMoment.jsではnow
自体の日付が変わっている一方で、Day.jsではnow
自体の日付は現在のまま変わっていないことがわかります。一般的にはDay.jsのように、メソッドを呼んだ際にオブジェクトの変更不可なimmutableな方が、バグを起こしにくいので推奨されています。
Moment.jsの場合
const now = moment(); // 08/20/2015
now.subtract(7, "year").format("MM/DD/YYYY"); // 08/20/2015
now.format("MM/DD/YYYY"); // 08/20/2015
Day.js
const now = dayjs(); // 08/20/2022
now.subtract(7, "year").format("MM/DD/YYYY"); // 08/20/2015
now.format("MM/DD/YYYY"); // 08/20/2022
まとめ
今回は日付操作について解説しました。開発ではよく使われる操作ですので、ぜひマスターしましょう。
次回はJavaScriptでの正規表現についてを解説します。