質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.46%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

2回答

412閲覧

3時点の日付の比較(p1,p2,p3)

pegy

総合スコア243

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2021/11/23 17:14

現在、基準日となる日付p1が以下のように代入されています。
最終的にはp1に近い日がp2であるのかp3であるのかを判定したいと考えております。

javascript

1var p1 = new Date("2021-11-30");

これに対して、比較すべき2つの日付p2とp3は年以外がわかっています。
また、もう一つわかっている条件としてp2とp3はちょうど6か月ずれているということです。

javascript

1var m = 8, d = 15 2//var p2 = new Date("????-"+m+"-"+d+"); 3 var next_m = "" 4 switch (m) { 5 case 1:next_m = 7;break; 6 case 2:next_m = 8;break; 7 case 3:next_m = 9;break; 8 case 4:next_m = 10;break; 9 case 5:next_m = 11;break; 10 case 6:next_m = 12;break; 11 case 7:next_m = 1;break; 12 case 8:next_m = 2;break; 13 case 9:next_m = 3;break; 14 case 10:next_m = 4;break; 15 case 11:next_m = 5;break; 16 case 12:next_m = 6;break; 17 } 18//var p3 = new Date("????-"+next_m+"-"+d+");

この場合p2の8月15日もp3の2月15日もp1の11月30日より前なので結果として????は2021というように判定することができます。

javascript

1var p1 = new Date("2021-11-30"); 2var p2 = new Date("2021-8-15"); 3var p3 = new Date("2021-2-15"); 4p1-p2 < p1 - p3 ? console.log("p2が近いです"):0;

Dateオブジェクトにして比較すればよいだけだと言いたいところですが、ここで悩ましい要素が2つあり頭が混乱しております。

  1. 例えば、p1は11月30日のままで、p2が6月15日でp3が12月15日であるパターンが来たとします。この時はp3の12月15日はp1の11月30日を超えてしまっているので、未到来の場合は2021ではなくその前のとしての2020であったとしなければなりません。

従って、このケースでは比べるものは以下の通りとなります。

javascript

1var p1 = new Date("2021-11-30"); 2var p2 = new Date("2020-12-15"); 3var p3 = new Date("2021-6-15"); 4p1-p2 < p1 - p3 ? 0:console.log("p3が近いです");
  1. 一方p2が例えば1月1日でp2とp3が元の月日であるとすると以下の通りになりp2とp3がいずれも未到来のため2020と解釈しなくてはいけません。

javascript

1var p1 = new Date("2021-1-1"); 2var p2 = new Date("2020-8-15"); 3var p3 = new Date("2020-2-15"); 4p1-p2 < p1 - p3 ? console.log("p2が近いです"):0;

とp1の値によって、p2とp3の年が変化したり、p2とp3のどちらかがp1を跨いでいる場合、どちらかの年を変化させたりとても複雑です。

ここまで、記載して説明ができるので、忠実に複雑な分岐を書けば実装はできると思うのですが、やろうとしていることが単純なのにp2とp3の年数が繰り下がったりというのが何かスマートに実装できる方法はないかと質問させていただきました。

アドバイスを頂ければ幸いです。よろしくお願い申し上げます。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

日付の操作で便利なDay.js を利用して、以下ようなcheck関数を作ってみました。

javascript

1// 2// 関数 check(p1, p2m, p2d, p3m) 3// 4// 引数: 5// p1: 基準の日付となるDateオブジェクト 6// p2m: 日付p2の月を表す整数(1始まり) 7// p2d: 日付p2の日を表す整数 8// p3m: 日付p3の月を表す整数(1始まり) 9// 10// 返される値: 以下のプロパティを含むオブジェクト 11// result: 判定結果の真偽値 (p2のほうがp1に近いならば true、そうでなければ false) 12// p2Year: 判定時に適用された、p2の年 13// p3Year: 判定時に適用された、p3の年 14// p2Diff: p2とp1の差(日数) 15// p3Diff: p3とp1の差(日数) 16// 17function check(p1, p2m, p2d, p3m) { 18 19 p1 = dayjs(p1); 20 21 const [p2, p3] = [[p2m, p2d], [p3m, p2d]].map(([m, d]) => { 22 const date = dayjs(`${p1.year()}-${m}-${d}`, 'YYYY-M-D'); 23 return date > p1 ? date.subtract(1, 'year') : date; 24 }); 25 26 const [p2Diff, p3Diff] = [p2, p3].map(p => p1.diff(p, 'day')); 27 28 return { 29 result: p2Diff < p3Diff, 30 p2Year: p2.year(), 31 p3Year: p3.year(), 32 p2Diff, 33 p3Diff 34 }; 35} 36 37

投稿2021/11/24 00:04

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

pegy

2021/11/24 02:37

ありがとうございます。関数まで作成いただいてしまって、誠に申し訳ございません。day.js存じ上げなかったです。こねこねPure JSでDateオブジェクトを複雑にいじっていたのですが、シンプルに扱えますね! また、関数の中身を見て考えかた汎用性が高そうなので、使いまわさせていただきます!
退会済みユーザー

退会済みユーザー

2021/11/24 02:54

dayjs いいですヨ。日時や日付の操作でよく出てくるやりたいことで、標準のDateだけだとツラ目なものが、ほとんど備わっています。
pegy

2021/11/24 03:37

副産物もあり、質問を投稿して良かったです! 改めて御礼を申し上げます。
guest

0

質問文に記載がありませんでしたが、本文の内容から「p2,p3よりもp1の方が日付が遅い」という条件が追加されているものとします。

p2,p3には暫定的に2021年の日付を代入しておき、それぞれについてp1よりも日付が遅ければ1年前にするという方法で、単純な分岐で実装できると思います。(「複雑」の基準にもよりますが)

↓コード例(2つ目のケース)

JavaScript

1var m = 12, d = 15; 2var next_m = (m - 1 + 6) % 12 + 1; 3 4var p1 = new Date("2021-11-30"); 5var p2 = new Date("2021-" + m + "-" + d); 6if (p1 < p2) { 7 p2.setFullYear(p2.getFullYear() - 1); 8} 9var p3 = new Date("2021-" + next_m + "-" + d); 10if (p1 < p3) { 11 p3.setFullYear(p3.getFullYear() - 1); 12} 13 14console.log(p1.getFullYear() + "-" + (p1.getMonth() + 1) + "-" + p1.getDate()); //出力: 2021-11-30 15console.log(p2.getFullYear() + "-" + (p2.getMonth() + 1) + "-" + p2.getDate()); //出力: 2020-12-15 16console.log(p3.getFullYear() + "-" + (p3.getMonth() + 1) + "-" + p3.getDate()); //出力: 2021-6-15 17 18if (p1 - p2 < p1 - p3) { 19 console.log("p2の方が近いです"); 20} 21else { 22 console.log("p3の方が近いです"); 23} 24//出力: p3の方が近いです 25

投稿2021/11/23 18:38

luuguas

総合スコア492

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

pegy

2021/11/24 02:31

行間まで読み取っていただき、ありがとうございます。私自身の頭が固いのか、単純にそれぞれ比較してgetFullYear() - 1とすればということでコードもすっきり見やすく腹落ちいたしました。 また、とてもお恥ずかしいのが半年ずれの月日を取得するのにswitchで地道に当て嵌めてしまいましたが、1未満の解になる剰余式のルールが理解できておらず、争点ではない「var next_m = (m - 1 + 6) % 12 + 1;」に一人で感動してしまいました。 いずれにしても御礼申し上げます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問