みなさんこんにちは、クローラ作成の鬼かい@dikxs118です。
今日は、JavaScriptのDate型の日付の大小の比較について解説したいと思います。Date型の日付の比較って、どういやったらいいか、なかなかうまい方法が浮かびづらいですよね。
そのため、
- Date型で日付の大小を比較したい!演算子はないの?
- Date型で日付のみの比較、時間のみの比較はどうするの?
- Date型でオブジェクト同士を比較するとどうなるの?
などの疑問が浮かぶのもうなづけます。これらはちょっとしたコツが必要です。
以下ではこれらを実現するコツを説明します。具体的には、
- Date型での日付の大小の比較(getTime()、<、>演算子)
- Date型で日付のみの比較
- Date型で時間のみの比較
- Date型でオブジェクト同士の比較
について、解説していきたいと思います。
最後にはJavaScriptを使って与えた時間が有効なものかどうかということを調べる関数も紹介したいと思います。
Date型で日時の大小の比較
getTime()による比較
Date型の日付の大小を比較する基本のメソッドは、Date#getTime()ですDate#getTime()は、Date型の日付をミリ秒に変換した数値を返します。
そのため、ミリ秒の大きさで日付の大小の比較が可能です。
比較はミリ秒までの精度しかできないため、マイクロ秒での大小の比較はできません。以下、実際にDate型の比較をDate#getTime()で行うコードを示します。
window.onload = function () { var date1 = new Date(2020, 4, 1, 12, 30, 45); var date2 = new Date(2020, 4, 30, 12, 30, 45); var date3 = new Date(2020, 4, 1, 12, 30, 45); console.log("date1.getTime() > date2.getTime() = " + (date1.getTime() > date2.getTime())); console.log("date1.getTime() < date2.getTime() = " + (date1.getTime() < date2.getTime())); console.log("date1.getTime() == date3.getTime() = " + (date1.getTime() == date3.getTime())); }
実行結果:
date1.getTime() > date2.getTime() = false date1.getTime() < date2.getTime() = true date1.getTime() == date3.getTime() = true
date1とdate2の日付の大小が正確に比較されていますね。また、同じ日付であるdate1とdate3は、比較の結果同じ日付であると判定されていますね。
<、>演算子による比較
Date型には、日付の大小を比較する<、>演算子が定義されています。
この演算子を用いれば、Date#getTime()を使用せずに日付の大小を比較できます。
window.onload = function () { var date1 = new Date(2020, 4, 1, 12, 30, 45); var date2 = new Date(2020, 4, 30, 12, 30, 45); console.log("date1 > date2 = " + (date1 > date2)); console.log("date1 < date2 = " + (date1 < date2)); }
実行結果:
date1 > date2 = false date1 < date2 = true
<、>演算子で日付の大小の比較がうまく行えていますね。
Date型で日付のみの比較
Date型で日付のみの比較を行うメソッドや演算子はありません。そのため、自分で実装する必要があります。
実装の手順としては、年、月、日の順に大小を比較します。以下のコードは、date1 < date2 という比較を日付のみで行う関数です。
window.onload = function () { var date1 = new Date(2020, 4, 1, 12, 30, 45); var date2 = new Date(2020, 4, 30, 12, 30, 45); var date3 = new Date(2020, 4, 1, 12, 30, 45); function lowerThanDateOnly(date1, date2) { var year1 = date1.getFullYear(); var month1 = date1.getMonth() + 1; var day1 = date1.getDate(); var year2 = date2.getFullYear(); var month2= date2.getMonth() + 1; var day2 = date2.getDate(); if (year1 == year2) { if (month1 == month2) { return day1 < day2; } else { return month1 < month2; } } else { return year1 < year2; } } console.log(lowerThanDateOnly(date1, date2)); console.log(lowerThanDateOnly(date1, date3)); }
実行結果:
true false
実行結果は以上のようになります。
上記で紹介したサンプルでは、Date型のインスタンスdata1~date3にそれぞれ日付を指定し、console.logでlowerThanDateOnly関数の引数に互いに比較する日付を渡して、比較結果を出力しています。
lowerThanDateOnly関数では、渡された日付型インスタンスの年月日を、Date#getXXX()系のメソッドでそれぞれ取得したあとにif文で年、月の順に比較していき、returnで日付を演算子で比較した結果を返します。
その結果、date1 < date2、date1 < date3 を日付のみで比較した結果となります。
date1 < date3 は同じ日付なので falseになることに注意してください。
Date型で時間のみの比較
Date型で時間のみの比較を行うメソッドや演算子もありません。そのため、自分で実装する必要があります。
実装の手順としては、時、分、秒の順に大小を比較します。以下のコードは、date1 < date2 という比較を時間のみで行う関数です。
window.onload = function () { var date1 = new Date(2020, 4, 1, 12, 30, 45); var date2 = new Date(2020, 4, 30, 12, 30, 45); var date3 = new Date(2020, 4, 1, 12, 30, 45); function lowerThanTimeOnly(date1, date2) { var hours1 = date1.getHours(); var minutes1 = date1.getMinutes(); var seconds1 = date1.getSeconds(); var hours2 = date2.getHours(); var minutes2 = date2.getMinutes(); var seconds2 = date2.getSeconds(); if (hours1 == hours2) { if (minutes1 == minutes2) { return seconds1 < seconds2; } else { return minutes1 < minutes2; } } else { return hours1 < hours2; } } console.log(lowerThanTimeOnly(date1, date2)); console.log(lowerThanTimeOnly(date1, date3)); }
実行結果:
false false
実行結果は以上のようになります。
上記で紹介したサンプルでは、Date型のインスタンスdata1~date3にそれぞれ日付を指定し、console.logでlowerThanTimeOnly関数の引数に互いに比較する日付を渡して、比較結果を出力しています。
lowerThanTimeOnly関数では、渡された日付型インスタンスの時分秒を、Date#getXXX()系のメソッドでそれぞれ取得したあとにif文で時、分の順に比較していき、returnで日付を演算子で比較した結果を返します。
その結果、date1 < date2、date1 < date3 を時刻のみで比較した結果となります。
date1とdate2は日付は異なっていても、時刻は同じなので、date1 < date2 がfalseになっていることに注意してください。
Date型でオブジェクト同士の比較
Date型には、<、>演算子が定義されていて、日付の大小の比較が可能でした。
しかし、Date型の == 演算子は、日付が一致することを比較する演算子ではありません。Date型の == 演算子は、Date型のインスタンスが一致するかどうかを比較する演算子です。
そのため、インスタンスが違う場合、== は false を返します。以下のコードは同じ日時ですが別々のインスタンス date1 とdate3 を == 演算子で比較しています。
window.onload = function () { var date1 = new Date(2020, 4, 1, 12, 30, 45); var date3 = new Date(2020, 4, 1, 12, 30, 45); console.log("date1 == date3 = " + (date1 == date3)); }
実行結果:
date1 == date3 = false
以上のように、== による比較結果は falseになりました。日時は同じでも、インスタンスが違うためです。
Date型で時間の計算を行う
これまでDate型同士の値の比較について解説してきましたが、ここではDate型にて時間を計算する方法を解説します。
一般的な日付の構成は”年、月、日、時、分、秒”であり、それぞれの値を取得/設定するメソッドがJavaScriptには用意されています。
そして、それらのメソッドを利用して時間の足し算(加算)、引き算(減算)を行うことができます。次に簡単なサンプルコードをご紹介します。
window.onload = function () { // 基本的な、日付の減算 var dt = new Date(2017, 4 , 5, 12, 50, 15); //1年後 dt.setFullYear(dt.getFullYear() + 1); //2か月後 dt.setMonth(dt.getMonth() + 2); //10日後 dt.setDate(dt.getDate() + 10); //12時間前 dt.setHours(dt.getHours() - 12); //30分前 dt.setMinutes(dt.getMinutes() - 30); //10秒前 dt.setSeconds(dt.getSeconds() - 10); console.log(dt); }
実行結果:
Wed Jul 15 2018 00:20:05 GMT+0900 (東京 (標準時))
日付の年月日時分秒などの各要素を専用メソッドで値を取得し、その値に’+’加算、’-’減算することで時間の計算ができることが確認できたかと思います。
JavaScriptの時間の計算方法についてさらに詳しく内容を知りたい方は以下の記事が参考になるので、ぜひ確認してみてください。
なお、細かい話ですがGMT+0900 (東京 (標準時))の部分は実行環境により表示が異なります。
- Internet Explorer・Microsoft Edgeの場合、(東京 (標準時))。
- Google Chromeの場合、 (日本標準時)。
- Safariでは(JST)となります。
どれも日本標準時(JST)を表しており、本質的な違いはありません。ブラウザごとの仕様の違いということで、気にせず学習を進めていってください。
日付をチェックする関数を作ろう
最後に存在する日付が正しいかどうかをチェックする関数を紹介しようと思います。関数といってもそのような便利な関数がJSでは用意されているわけではありません。
なので関数を自作してみましょう。まずは、全体像から見ていきます。
function correct_date(puts, point) { var array = puts.split(point); if (array.length != 3) { return false; }; var date = new Date(array[0], array[1] - 1, array[2]); if (array[0] == date.getFullYear() && array[1] == ('0' + (date.getMonth() + 1)).slice(-2) && array[2] == ('0' + date.getDate()).slice(-2)) { return true; } else { return false; } }; console.log(correct_date('2017/03/04', '/')); console.log(correct_date('2017/3/4', '/')); console.log(correct_date('2017/08/32', '/')); console.log(correct_date('2018/02/29', '/')); console.log(correct_date('2019/02/29', '/')); console.log(correct_date('2020/02/29', '/')); console.log(correct_date('2020-02-29', '-'));
実行結果:
true false false false false true true
はい、見てもらえば大体わかると思いますが、簡単にコードレビューをしておきましょう!
correct_date関数に入力値であるputsと区切り文字のpointを与えます。2行目でarrayに区切り文字で区切られた値を入れていきます。基本的に入力値は、y,m,dの3つの入力値を入れることを想定しているので、arrayの中に3つ値が入っていなければその時点でFalseを返します。
そしてその区切られた3つの値をnew Dateにより日付に変換しています。因みに、Monthの領域が-1されているのは基準月を0月と考えているためです。
次に、3つの値一つ一つに対して、getFullyer,getMonth,getDateなどにより値が正しいかを判断して、全て正しければtrue、一つでもおかしな日付があればFalseを返します。
プログラムとしてはとても簡単なプログラムですが、言葉に表してもわかりにくいので実際に書いてみることをおすすめします。
結果をみてみると、最後がtrueになっていることからうるう年も区別していることがわかります。
日付の使い方総まとめ
日付の様々な使い方についてはこちらの記事で詳しく解説しているので、ぜひ確認してください。
まとめ
いかがでしたでしょうか?
JavaScriptのDate型の大小の比較には、Date#getTime()というミリ秒の精度で比較する方法がありましたね。また、Date#getTime()を使用せずとも、Date型には日付の大小を比較する <、> 演算子もあります。
ただし、== 演算子は日付が同一かどうかを比較する演算子ではなく、インスタンスが同一かどうかを比較する演算子です。
日付が妥当なものであるかどうかをチェックする関数もご紹介しました。
これはこのままコードに貼り付ければほしいところで呼び出せたりもできるので、記事を参考にして中身を理解した上で使ってみてください!それでは!!