web-dev-qa-db-ja.com

JavaScriptで時間を比較せずに日付部分のみを比較する

以下のコードの何が問題になっていますか

たぶんそれは時間ではなく単に日付を比較する方が簡単でしょう。私もこれを行う方法がわからない、と私は検索したが、私は私の正確な問題が見つからなかった。

ところで、アラートに2つの日付を表示すると、まったく同じように表示されます。

私のコード:

window.addEvent('domready', function() {
    var now = new Date();
    var input = $('datum').getValue();
    var dateArray = input.split('/');
    var userMonth = parseInt(dateArray[1])-1;
    var userDate = new Date();
    userDate.setFullYear(dateArray[2], userMonth, dateArray[0], now.getHours(), now.getMinutes(), now.getSeconds(), now.getMilliseconds());

    if (userDate > now)
    {
        alert(now + '\n' + userDate);
    }
});

日付を比較して時間を含まないより簡単な方法はありますか?

332
moleculezz

私はまだJavaScriptを学んでいます、そして私が見つけることができた唯一の方法は私が時間なしで2つの日付を比較するのに役立つことです setHours Dateオブジェクトの) メソッドを使用して、時、分、秒、ミリ秒をゼロに設定します。それから2つの日付を比較しなさい。

例えば、

date1 = new Date()
date2 = new Date(2011,8,20)

date2は、時、分、秒、ミリ秒でゼロに設定されますが、date1では、date1が作成された時刻に設定されます。 date1の時、分、秒、ミリ秒を削除するには、次の手順に従います。

date1.setHours(0,0,0,0)

これで、時間要素を気にせずに2つの日付を日付としてのみ比較できます。

695
nexar

タイムゾーンを見る

日付オブジェクトを使用して日付だけを表すと、非常に大きな精度の問題が発生します。あなたはそれらを締め出すために時間とタイムゾーンを管理する必要があります、そして彼らはどんなステップでも潜入することができます。 この質問に対する受け入れられた答えは罠に入ります。

JavaScriptの日付にはタイムゾーンの概念なしがあります。デフォルトではデバイスの「ローカル」タイムゾーン、または指定されている場合はUTCまたは別のタイムゾーンを使用して、文字列との間で変換するための便利な(静的)機能を備えた瞬間的なものです。日付オブジェクトで日付を表すには、 問題の日付の開始日の深夜0時をUTCで表すようにします。 これは、作成の季節やタイムゾーンに関係なく、日付を使って作業できるようにするための一般的で必要な規則です。そのため、真夜中のUTC Dateオブジェクトを作成するときとそれをシリアル化するときの両方で、タイムゾーンの概念を管理するには非常に慎重になる必要があります。

多くの人がコンソールのデフォルトの動作に混乱しています。コンソールに日付をスプレーすると、表示される出力にはタイムゾーンが含まれます。これは、コンソールがあなたの日付にtoString()を呼び出し、そしてtoString()があなたにローカルな表現を与えるからです。基礎となる日付にはタイムゾーンがありません! (時間がタイムゾーンオフセットと一致する限り、午前0時のUTC日付オブジェクトが残っています)

シリアル化解除(または真夜中のUTC Dateオブジェクトの作成)

ほとんどの場合、あなたの日付にはユーザーのタイムゾーンを反映させたいでしょう。 今日があなたの誕生日であればクリックしてください 。ニュージーランドと米国のユーザーは同時にクリックして異なる日付を取得します。その場合、これをしてください...

// create a date (utc midnight) reflecting the value of myDate and the environment's timezone offset.
new Date(Date.UTC(myDate.getFullYear(),myDate.getMonth(), myDate.getDate()));

時には、国際的な比較可能性が地域の正確性を上回る。その場合、これをしてください...

// the date in London of a moment in time. Device timezone is ignored.
new Date(Date.UTC(myDate.getUTCFullYear(), myDate.getUTCMonth(), myDate.getUTCDate()));

日付をデシリアライズする

多くの場合、ネットワーク上の日付はYYYY-MM-DDの形式になります。それらを逆シリアル化するには、次のようにします。

var midnightUTCDate = new Date( dateString + 'T00:00:00Z');

直列化

作成時にタイムゾーンを管理するように注意を払ったので、今度は文字列表現に変換するときに必ずタイムゾーンをタイムアウトにしておく必要があります。 それで、あなたは安全に使うことができます...

  • toISOString()
  • getUTCxxx()
  • getTime() //returns a number with no time or timezone.
  • .toLocaleDateString("fr",{timezone:"UTC"}) // whatever locale you want, but ALWAYS UTC.

そして、特に他のすべてのものを完全に避けてください。

  • getYear()getMonth()getDate()

それであなたの質問に答えるために、7年も遅すぎます...

<input type="date" onchange="isInPast(event)">
<script>
var isInPast = function(event){
  debugger;
  var userEntered = new Date(event.target.valueAsNumber); // valueAsNumber has no time or timezone!
  var now = new Date();
  var today = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate() ));
  if(userEntered.getTime() < today.getTime())
    alert("date is past");
  else if(userEntered.getTime() == today.getTime())
    alert("date is today");
  else
    alert("date is future");

}
</script>

実行中です...

72
bbsimonbb

これはどう?

Date.prototype.withoutTime = function () {
    var d = new Date(this);
    d.setHours(0, 0, 0, 0);
    return d;
}

変数の値に影響を与えずに、このように日付の日付部分を比較できます。

var date1 = new Date(2014,1,1);
new Date().withoutTime() > date1.withoutTime(); // true
66
AdEpt

Moment.js を使う

サードパーティのライブラリを含めるという選択肢がある場合は、 Moment.js をご覧ください。 DateDateTimeを扱うのがずっと簡単になります。

たとえば、あるDateが別のDateの後に来るが、それらの時間は除外されているかどうかを確認するには、次のようにします。

var date1 = new Date(2016,9,20,12,0,0); // October 20, 2016 12:00:00
var date2 = new Date(2016,9,20,12,1,0); // October 20, 2016 12:01:00

// Comparison including time.
moment(date2).isAfter(date1); // => true

// Comparison excluding time.
moment(date2).isAfter(date1, 'day'); // => false

isAfterに渡す2番目のパラメーターは、比較を行うための精度で、yearmonthweekdayhourminute、またはsecondのいずれかになります。

21
Joshua Pinter

以下のように単に.toDateStringを使って比較してください。

new Date().toDateString();

次のように、日付部分だけを返し、時間やタイムゾーンは返しません。

"2017年2月3日金曜日"

それゆえ、両方の日付は、その時間部分なしで同様にこのフォーマットで比較することができる。

9
Rahi

これはもう少しきれいなバージョンかもしれません、またparseIntを使うときあなたは常に基数を使うべきであることに注意してください。

window.addEvent('domready', function() {
    // Create a Date object set to midnight on today's date
    var today = new Date((new Date()).setHours(0, 0, 0, 0)),
    input = $('datum').getValue(),
    dateArray = input.split('/'),
    // Always specify a radix with parseInt(), setting the radix to 10 ensures that
    // the number is interpreted as a decimal.  It is particularly important with
    // dates, if the user had entered '09' for the month and you don't use a
    // radix '09' is interpreted as an octal number and parseInt would return 0, not 9!
    userMonth = parseInt(dateArray[1], 10) - 1,
    // Create a Date object set to midnight on the day the user specified
    userDate = new Date(dateArray[2], userMonth, dateArray[0], 0, 0, 0, 0);

    // Convert date objects to milliseconds and compare
    if(userDate.getTime() > today.getTime())
    {
            alert(today+'\n'+userDate);
    }
});

基数についての詳細は、MDC parseInt ページをご覧ください。

JSLint は、基数が足りないなど、あいまいでデバッグが困難なエラーを検出するための素晴らしいツールです。将来の頭痛を避けるために、より良いコーディング標準を使用する必要があります。私がコーディングするすべてのJavaScriptプロジェクトでそれを使用します。

8
Useless Code

date.js ライブラリはこれらのことに便利です。それはすべてのJSの日付関連のスクリプト作成をずっと簡単にします。

これが私のやり方です。

var myDate  = new Date($('input[name=frequency_start]').val()).setHours(0,0,0,0);
var today   = new Date().setHours(0,0,0,0);
if(today>myDate){
    jAlert('Please Enter a date in the future','Date Start Error', function(){
        $('input[name=frequency_start]').focus().select();
    });
}
3
Fabrizio

datename__オブジェクトが変更されたローカルタイムゾーンに正確に移行すると問題が発生する可能性があるため、ここでは似たようなアプローチが見られず、h/m/s/msを0に設定するのは嬉しくありません。少し前に書いた、lil関数です。

+:使いやすく、基本的な比較操作を実行します(時間なしで日、月、年を比較します)。
-:これは「箱から出して」考えることとは完全に反対のようです。

function datecompare(date1, sign, date2) {
    var day1 = date1.getDate();
    var mon1 = date1.getMonth();
    var year1 = date1.getFullYear();
    var day2 = date2.getDate();
    var mon2 = date2.getMonth();
    var year2 = date2.getFullYear();
    if (sign === '===') {
        if (day1 === day2 && mon1 === mon2 && year1 === year2) return true;
        else return false;
    }
    else if (sign === '>') {
        if (year1 > year2) return true;
        else if (year1 === year2 && mon1 > mon2) return true;
        else if (year1 === year2 && mon1 === mon2 && day1 > day2) return true;
        else return false;
    }    
}

使用法:

等価性チェックのためのdatecompare(date1, '===', date2)
datecompare(date1, '>', date2)チェックを強化
!datecompare(date1, '>', date2)以下または同等のチェック

また、明らかに、date1date2を入れ替えて他の単純な比較を行うことができます。

3
Max Yari

それが投稿されたのと全く同じ時間にこの質問を読んだ後、私は少なくとも自分のニーズにはそれほど満足できるほどそれを見つけることができなかったので、私は別の解決策を投稿することにしました。

私はこのようなものを使いました:

var currentDate= new Date().setHours(0,0,0,0);

var startDay = new Date(currentDate - 86400000 * 2);
var finalDay = new Date(currentDate + 86400000 * 2);

このようにして、後で処理するために必要な形式で日付を使用することができました。しかし、これは私の必要性のためだけでした、しかし私はとにかくそれを投稿することにしました、多分それは誰かを助けるでしょう

2
Aleks

日付を比較するための効率的で正しい方法は次のとおりです。

Math.floor(date1.getTime() / 86400000) > Math.floor(date2.getTime() / 86400000);

それは時間の部分を無視します、それは異なるタイムゾーンのために働きます、そしてあなたは同等性のためにあなたも比較することができます==。 86400000は1日のミリ秒数です(= 24*60*60*1000)。

2つのDateオブジェクトを比較しているため(および2つの日付を比較していないため)、等価性テストが機能すると予想される場合は失敗するため、等価演算子==はDateオブジェクトの比較にneverを使用する必要がある例:

> date1;
outputs: Thu Mar 08 2018 00:00:00 GMT+1300

> date2;
outputs: Thu Mar 08 2018 00:00:00 GMT+1300

> date1 == date2;
outputs: false

> Math.floor(date1.getTime() / 86400000) == Math.floor(date2.getTime() / 86400000);
outputs: true

注意:時間部分がゼロに設定されているDateオブジェクトを比較している場合は、date1.getTime() == date2.getTime()を使用できますが、最適化する価値はほとんどありません。 Dateオブジェクトを直接比較するときは、<><=、または>=を使用できます。これらの演算子は、比較を行う前にまず.valueOf()を呼び出してDateオブジェクトを変換するためです。

2
robocat

時間コンポーネントなしで本当に日付を比較するのであれば、Date()の時間とタイムゾーンの頭痛の種をすべて避け、うまくいく可能性がある別の解決策は、文字列比較を使用してISO文字列の日付を直接比較することです。

> "2019-04-22" <= "2019-04-23"
true
> "2019-04-22" <= "2019-04-22"
true
> "2019-04-22" <= "2019-04-21"
false
> "2019-04-22" === "2019-04-22"
true

次のようにして現在の日付(UTCの日付、必ずしもユーザーのローカルの日付ではない)を取得できます。

> new Date().toISOString().split("T")[0]
"2019-04-22"

それを支持する私の主張はプログラマーの単純さです - おそらく速度を犠牲にして、日時とオフセットを正しく処理しようとするよりも、これを駄目にする可能性ははるかに低いです(私はパフォーマンスを比較していません)。

1
brittohalloran

あなたは、msの合計でいくらかの算術を使うことができます。

var date = new Date(date1);
date.setHours(0, 0, 0, 0);

var diff = date2.getTime() - date.getTime();
return diff >= 0 && diff < 86400000;

元の日付への更新は行われず、文字列の分割と比較よりも速く実行されるので、これが好きです。

この助けを願っています!

1
Miguel

必ずsetFullYear(10, ...) !== setFullYear(2010, ...)として4桁の年でuserDateを作成してください。

1
Alex K.

このJSは設定日の後に内容を変更します これは同じことですがw3schools

date1 = new Date()
date2 = new Date(2019,5,2) //the date you are comparing

date1.setHours(0,0,0,0)

var stockcnt = document.getElementById('demo').innerHTML;
if (date1 > date2){
document.getElementById('demo').innerHTML="yes"; //change if date is > set date (date2)
}else{
document.getElementById('demo').innerHTML="hello"; //change if date is < set date (date2)
}
<p id="demo">hello</p> <!--What will be changed-->
<!--if you check back in tomorrow, it will say yes instead of hello... or you could change the date... or change > to <-->
0
NICHOLAS WOJNAR

setHours()と比較すると解決策になります。サンプル:

var d1 = new Date();
var d2 = new Date("2019-2-23");
if(d1.setHours(0,0,0,0) == d2.setHours(0,0,0,0)){
    console.log(true)
}else{
    console.log(false)
}
0

Fp_incr(0)を使用できます。タイムゾーン部分を真夜中に設定し、日付オブジェクトを返します。

0
user2849789

両方の日付にtoDateString()を使用するだけです。 toDateStringには時刻が含まれていないため、同じ日付の2回の場合、値は以下のように等しくなります。

var d1 = new Date(2019,01,01,1,20)
var d2 = new Date(2019,01,01,2,20)
console.log(d1==d2) // false
console.log(d1.toDateString() == d2.toDateString()) // true

明らかに、この質問に関して他の場所で表現されたタイムゾーンの懸念のいくつかは有効です、しかし多くのシナリオでは、それらは関連性がありません。

0
Mike Feltman
var fromdate = new Date(MM/DD/YYYY);
var todate = new Date(MM/DD/YYYY);
if (fromdate > todate){
    console.log('False');
}else{
    console.log('True');
}

あなたの日付フォーマットが違う場合は、 moment.js ライブラリを使用して日付のフォーマットを変換してから上記のコードを使用して2つの日付を比較

例:

あなたの日付が "DD/MM/YYYY"であり、それを "MM/DD/YYYY"に変換したい場合は、以下のコード例をご覧ください。

var newfromdate = new Date(moment(fromdate, "DD/MM/YYYY").format("MM/DD/YYYY"));
console.log(newfromdate);
var newtodate = new Date(moment(todate, "DD/MM/YYYY").format("MM/DD/YYYY"));
console.log(newtodate);

0
Pritesh Singh

私はこの質問がすでに答えられていて、これが最善の方法ではないかもしれないことを知っています、しかし私のシナリオではそれは完全に働いているので、私はそれが私のような人を助けるかもしれないと思いました。

date string

String dateString="2018-01-01T18:19:12.543";

そして、あなたは単に日付の部分をJSの他のDateオブジェクトと比較したいだけです。

var anotherDate=new Date(); //some date

new Date("2018-01-01T18:19:12.543");を使ってconvert to stringオブジェクトをDateにする必要があります

そしてここにトリックがあります: -

var valueDate =new Date(new Date(dateString).toDateString());

            return valueDate.valueOf() == anotherDate.valueOf(); //here is the final result

JSのDate objecttoDateString()を使いました。これはDate文字列だけを返します。

注:日付を比較するときには.valueOf()関数を使用することを忘れないでください。

.valeOf()に関する詳細情報はこちら リファレンス

幸せなコーディング。

0
R K Sharma

これは助けになるでしょう。私はこれをどうにかして実現しました。

var currentDate = new Date(new Date().getFullYear(), new Date().getMonth() , new Date().getDate())
0