JavaScriptの日付操作【プログラミング初心者向け教材】

プログラミング

日付の生成、加算・減算、比較、フォーマットなどの操作は、プログラミングでよくある操作の1つです。

データベースやAPIなどで外部と日付データを送受信する際には、決まったフォーマットにする必要があります。

そのため、プログラミング初心者にとって、日付操作は学習すべき事項の1つとなります。

本記事では、JavaScriptのよく使われる日付操作について解説します。

プログラミング初心者の方の学習や、忘れてしまった方の復習として、参考にしていただければ幸いです。

記載しているプログラムは、Node.js12.18.4を使って動作確認をしています。

JavaScriptの日付操作

よくある日付操作として、以下の内容を採り上げます。

  • 日時の生成
  • 日時の加算・減算
  • 日時の差分
  • 日時の比較
  • 日時から文字列へのフォーマット
  • 文字列から日時への変換
  • ライブラリの利用

日付の生成

日付を扱うには、Dateオブジェクトを使います。

日付を生成するには、大きく2つの方法があります。

現在時刻で生成する方法

d = new Date();
console.log(d.toLocaleString()); // -> 2020-10-19 10:08:30

任意の日時を指定する方法

d = new Date(2020, 9, 19, 9, 0, 0, 0);
console.log(d.toLocaleString()); // -> 2020-10-19 9:00:00

月の指定は-1する点に注意が必要です。(1月とするには0を指定します)

d = new Date('2020/10/19 09:00:00');
console.log(d.toLocaleString());

文字列を指定する方法は、フォーマットやブラウザの種類等によって結果が異なる場合がありますので注意が必要です。

日時の加算・減算

日時の加算や減算を行うには、Dateオブジェクトに対して、加算・減算したい値をsetメソッドで指定します。

日時の加算

d = new Date(2020, 0, 1); // 2020/1/1 00:00:00 で生成
d.setFullYear(d.getFullYear() + 1); // 一年を加算
d.setMonth(d.getMonth() + 1); // 一月を加算
d.setDate(d.getDate() + 1); // 一日を加算
d.setHours(d.getHours() + 1); // 一時間を加算
d.setMinutes(d.getMinutes() + 1); // 一分を加算
d.setSeconds(d.getSeconds() + 1); // 一秒を加算
console.log(d.toLocaleString()); // -> 2021-2-2 1:01:01

日時の減算

// 日時の減算
d = new Date(2020, 0, 1); // 2020/1/1 00:00:00 で生成
d.setFullYear(d.getFullYear() - 1); // 一年を減算
d.setMonth(d.getMonth() - 1); // 一月を減算
d.setDate(d.getDate() - 1); // 一日を減算
d.setHours(d.getHours() - 1); // 一時間を減算
d.setMinutes(d.getMinutes() - 1); // 一分を減算
d.setSeconds(d.getSeconds() - 1); // 一秒を減算
console.log(d.toLocaleString()); // -> 2018-11-29 22:58:59

日時の差分

Dateオブジェクト同士の日時の差分を取得するには、エポックミリ秒(1970年1月1日 00:00:00から経過したミリ秒)の差分で計算します。

d1 = new Date(2020, 0, 1); // 2020/1/1 00:00:00
d2 = new Date(2020, 9, 19, 0, 0, 0); // 2020/10/19 00:00:00
diff = d2.getTime() - d1.getTime();
console.log(diff); // -> 25228800000

// 差分を日にち計算(今年の経過日数を計算)
console.log(diff / (1000*60*60*24)); // -> 292

日時の比較

日時の新古を比較にするには、差分と同じくエポックミリ秒で比較します。

// "d2の方が新しい"が表示される
d1 = new Date(2020, 0, 1); // 2020/1/1 00:00:00
d2 = new Date(2020, 0, 1, 0, 0, 1); // 2020/1/1 00:00:01
if (d1.getTime() < d2.getTime()) {
    console.log("d2の方が新しい");
} else if (d1. getTime() > d2.getTime()) {
    console.log("d1の方が新しい");
} else {
    console.log("d1とd2は同じ")
}

日時から文字列へのフォーマット

Dateから文字列へのフォーマットは、Dateオブジェクトが提供するメソッドを利用する方法と、テンプレートリテラルを用いる方法があります。

Dateオブジェクトが提供するメソッドを利用する方法

この方法は、簡単に扱えますが、フォーマット形式が限定されていることに注意が必要です。

d = new Date(2020, 9, 19, 10, 2, 3);
console.log(d.toDateString()); // -> Mon Oct 19 2020
console.log(d.toGMTString()); // -> Mon, 19 Oct 2020 01:02:03 GMT
console.log(d.toISOString()); // -> 2020-10-19T01:02:03.000Z
console.log(d.toLocaleDateString()); // -> 2020-10-19
console.log(d.toLocaleString()); // -> 2020-10-19 10:02:03
console.log(d.toLocaleTimeString()); // -> 10:02:03
console.log(d.toTimeString()); // -> 10:02:03 GMT+0900 (GMT+09:00)
console.log(d.toUTCString()); // -> Mon, 19 Oct 2020 01:02:03 GMT

テンプレートリテラルを用いる方法

この方法は、好きなフォーマット形式にできますが、複雑になります。

d = new Date(2020, 9, 19, 10, 2, 3);
s = `${d.getFullYear()}/${d.getMonth()+1}/${d.getDate()} ${d.getHours()}:${d.getMinutes()}:${d.getSeconds()}`
console.log(s); // -> 2020/10/19 10:2:3

// 2桁で表示するように0埋め
s = `${d.getFullYear()}/${(d.getMonth()+1).toString().padStart(2, '0')}/${d.getDate().toString().padStart(2, '0')} ${d.getHours().toString().padStart(2, '0')}:${d.getMinutes().toString().padStart(2, '0')}:${d.getSeconds().toString().padStart(2, '0')}`
console.log(s); // -> 2020/10/19 10:02:03

文字列から日時への変換

文字列からDateへ変換するには、Dateオブジェクトのparseメソッドでエポックミリ秒に変換後、Dateオブジェクトを作成します。

s = "2020/10/19 01:02:03";
d = new Date(Date.parse(s));
console.log(d.toLocaleString()); // -> 2020-10-19 1:02:03

変換可能な文字列のフォーマットは、ブラウザや実行環境によって異なる場合があるので注意が必要です。

ライブラリの利用

標準で提供されている機能だけでは、プログラミングが複雑になる場合があります。
そんな時にライブラリを利用すると簡単に実装できることがあります。
今回は2つ紹介します。

Moment.js

Moment.jsは、日付処理を簡単に行える有名なライブラリですが、現在はメンテナンスを終了しています。
新しいプロジェクトでは使用しないことが推奨されています。

moment = require('moment');
d = moment('2020-10-19', 'YYYY-MM-DD');
console.log(d.format()); // -> 2020-10-19T00:00:00+09:00
console.log(d.format('YYYY/MM/DD HH:mm:ss')); // -> 2020/10/19 00:00:00

Luxon.js

Luxon.jsは、Moment.jsの後継とされているライブラリです。

luxon = require('luxon');
d = luxon.DateTime.local(2020, 10, 19);
console.log(d.toString()); // -> 2020-10-19T00:00:00.000+09:00
console.log(d.toFormat('yyyy/MM/dd HH:mm:ss')); // -> 2020/10/19 00:00:00

日付操作には十分なテストが必要

日付と文字列を変換していると、環境によって時間が変わってしまうことがあります。

また、クライアントで保持している時間とサーバで保持している時間が変わってしまうなどもあります。

こうした環境による変化は、タイムゾーンが原因であることが考えられます。

実際のプロジェクトでは、データベースはどのタイムゾーンなのか、サーバはどのタイムゾーンで設定するのか、クライアントはどのタイムゾーンで表示するのかといったことを最初に決めておく必要があります。

これらを統一しておかないと、意図せず異なった日時で保存されてしまったり、処理が動いてしまったりといったことが発生します。

また、うるう年やうるう秒など、特定の時にだけ発生する時間差などもあります。

過去にもこうした対策がきちんと行われていないことが原因で、大きなトラブルになった事例もあります。

日付を扱う際には、実装時にも注意し、テストを十分に行うことをおすすめします。

今回はJavaScriptの日付操作について紹介しました。

参考になれば幸いです。

コメント

タイトルとURLをコピーしました