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

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

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

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

正規表現

正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

Q&A

解決済

3回答

3696閲覧

Javascriptで日付をうるう年も考慮し正規表現で書きたい!!

t_t_t_t_t_t

総合スコア10

JavaScript

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

正規表現

正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

0グッド

1クリップ

投稿2020/02/14 02:16

編集2020/03/17 14:10

年と月の正規表現は分かりましたが、日付の正規表現が分かりません。年月日の入力をチェックしてエラーを出しているのですが現状のコードだと日付だけ何を打ってもエラーが出ます。分かる方教えて頂きたいです。

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

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

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

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

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

m.ts10806

2020/02/14 02:36

マークダウンは適切に使ってください。
t_t_t_t_t_t

2020/02/14 02:45

承知しました。ご指摘ありがとうございます。
m.ts10806

2020/02/14 03:02

細かいですが冒頭の文章全部太字(見出し?)にしなくても良いかと。
t_t_t_t_t_t

2020/02/14 03:03

確かにそうですね。編集しました。有り難うございます。
guest

回答3

0

ベストアンサー

まぁ完全に妥当電話番号や郵便番号ですらあるので、そりゃ探せば出てきますよね。
閏年を判定する正規表現を構築し、その完全性を理論的に検証 - Qiita

ここからが問題ですが、これを提出された講師はびっくりして問い詰めますよ?
「これをどうやって作ったのか?」とね。
使うからには最低限記事の中身と同じ事をペラペラ答えられるよう勉強しておくべきです。

個人的にはそれは辛いので、
数値に変換して4倍や100倍でチェックしながら判断した方が良いと思います。

js

1function isLeapYear(year) { 2 if (year % 400 == 0) return true; 3 if (year % 100 == 0) return false; 4 if (year % 4 == 0) return true; 5 return false; 6} 7 8[2400, 2300, 2200, 2004, 2001].forEach(function(year){ 9 console.log(isLeapYear(year)); 10}); 11// true 12// false 13// false 14// true 15// false

これなら1分で作れます。


JavaScript流儀ならDate型を利用するのも良いと思います。

js

1// monthだけindexなので数値が1ずれるのに注意 2[2400, 2300, 2200, 2004, 2001].forEach(function(year){ 3 console.log(new Date(year, 1, 29)); 4}); 5// Tue Feb 29 2400 00:00:00 GMT+0900 (日本標準時) 6// Thu Mar 01 2300 00:00:00 GMT+0900 (日本標準時) 7// Sat Mar 01 2200 00:00:00 GMT+0900 (日本標準時) 8// Sun Feb 29 2004 00:00:00 GMT+0900 (日本標準時) 9// Thu Mar 01 2001 00:00:00 GMT+0900 (日本標準時)

閏年の時は28日しかありませんので、
new Date()で日付を作る時に29日を指定すると+1日されて勝手に3月1日になります。
後は3月になっているか否かをチェックして取り出せば関数化出来ます。

js

1function isLeapYear(year) { 2 return (new Date(year, 1, 29)).getMonth() != 2; 3} 4 5[2400, 2300, 2200, 2004, 2001].forEach(function(year){ 6 console.log(isLeapYear(year)); 7}); 8// true 9// false 10// false 11// true 12// false

因みに業務なら世界中で使われているMoment.jsを選択するケースが多いでしょう。
更に関数型として発展・改良されたLUXONライブラリもあり、どちらを使うかという感じです。

どちらにせよ、日付を放り込んで
正しい日付ですか?と聞いてfalseが帰ってきたら不正な数値と返すだけなので
後々の処理を考えた時は絶対にライブラリ使う方が良いです。


【おまけ】 カイジくんが本当に欲しいのはこっち

年月日の入力をチェックしてエラーを出している

閏年なんてどうでも良いんですよ。
妥当な日付か否かが知りたいんでしょ?

まぁ、これ一択でしょうね。
数値へのキャストはNumberを使いましょう。

js

1// 文字列を数値にしたい 2console.log(Number("2000")); // 2000 3 4function isValidDate(year, month, day) { 5 var d = (new Date(year, month - 1, day)); 6 return year == d.getFullYear() 7 && month - 1 == d.getMonth() 8 && day == d.getDate(); 9} 10 11[2400, 2300, 2200, 2004, 2001].forEach(function(year){ 12 console.log(isValidDate(year, 2, 29)); 13}); 14// true 15// false 16// false 17// true 18// false 19 20// 完全に存在しない不正な日付も繰り上がったりするので 21console.log(new Date(2000, 3, 32)); // Tue May 02 2000 00:00:00 GMT+0900 (日本標準時) 22console.log(isValidDate(2000, 4, 32)); // false

【おまけのおまけ】 エラーが出たら消えないのでそこも分かる方がいらっしゃったら教えて頂きたいです。

JavaScriptが出来る事は
HTMLの構造をA→Bに書き換えることだけです。
壊したらもう元には戻りません。

これはJavaScriptが命令型言語なので指示待ち人間なわけですよ。
指示を出すからには、「妥当な日付になったら戻れ!」という指示が必要になります。

エラーを表示する為にelm.innerHTML = "エラーですよ"みたいな事をやってますよね?
だから日付が妥当だった場合は、自らの手でelm.innerHTML = ""と消さなければなりません。
これはjQueryへ移行しても記述が簡素になってちょっと楽になる程度で変わりません。

最終的にはテンプレートを渡して、
「Aの変数を見て、Aの変数が変更されたら勝手に最善の形に書き換わってくれ!」という仕組みを構築するのが終着点です。
これを実現するのがReactやVue.js等のJSフレームワークを駆使した開発です。

恐らく今後の講義として追加されると思うので楽しみにしてください。

投稿2020/02/14 03:05

編集2020/02/14 03:40
miyabi-sun

総合スコア21158

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

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

t_t_t_t_t_t

2020/02/14 04:01

いくつもの方法を教えて頂きありがとうございます。 今の現状はおまけのおまけだけ参考にし解決しました。 他のを参考にしたいのですが、自分の勉強不足で理解ができていません。 私のやりたいことは、年月日から曜日を出すことです。 その際には正規表現でなくても良いのですが、閏年を考慮してエラーかエラーで無いかを出し、エラーでない場合に検索ボタンを押し曜日が出すことです。これを踏まえて一番参考になるのは、どのコードになるのでしょうか??初心者でも分かるように教えて頂きたいです。
t_t_t_t_t_t

2020/02/14 04:12 編集

javascriptでやりたいです。
maisumakun

2020/02/14 04:20

new Dateで日付を作っているのだから、「入力した年・月・日」と「生成したDateオブジェクトの年・月・日」を比較して、違う値になっていたら「日付が正しくなかった」と判断できます。
jun68ykt

2020/02/14 04:35

横から失礼いたします。 miyabi-sunさんの回答の中で、 Moment.js が挙げられていまして、私も Moment を使うだろうなと思ったので、サンプルを作成してみました。以下です。 https://codepen.io/jun68ykt/pen/MWwKEXd?editors=1010 入力欄には YYYY-MM-DD 形式で年月日を入力して、[検証]ボタンをクリックすると、その年月日が妥当かを判定して、(2020-02-29などの)妥当な日付ならば、OKと曜日を結果に表示します。2019-02-29など、妥当でなければNGと表示されます。 妥当であるかどうかの判定には、 isValid() https://momentjs.com/docs/#/parsing/is-valid/ というメソッドが用意されており、これを使っています。
t_t_t_t_t_t

2020/03/02 07:39 編集

Moment.jsはとても便利なんだろうなと思いました。
m.ts10806

2020/02/14 05:34 編集

Moment.jsもjsですよ。もっと言えばjQueryもjs。 たぶんそういうことじゃないでしょうけど、表現によって意図は伝わりづらいと思います。 Vanilla JSとかPure JSとかそれっぽい表現はありますが、手っ取り早く要件満たせるのはライブラリ利用なのは間違いないです。 単なる課題なら「あ、そう頑張って」というだけですね。 自分でやらなきゃ課題の意味ありません。
guest

0

日付の正規表現が分かりません。

そもそも論として、年月日が正しいことは、正規表現でチェックするには複雑過ぎます

正規表現でチェックするのはせいぜい「日付が1~31までの値であること」ぐらいにして、別なルーチンでチェックする、もしくは月日はドロップダウン式にして不適切な値を最初から入力できなくする、ような方策のほうが適当かと思います。

投稿2020/02/14 02:23

maisumakun

総合スコア145184

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

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

maisumakun

2020/02/14 02:27

さらに細かいことを言い始めると、現行のグレゴリオ暦が最初に使われたのが「1582年10月15日」のことなので(日本は明治時代になってからなど、国によってはそれより遅いところもある)、それ以前の日付には現行のルールは適用できません。
t_t_t_t_t_t

2020/02/14 02:55

年月日が正しいことは、正規表現でチェックするには複雑過ぎるということを知りませんでした。 グレゴリオ暦の件については、年の正規表現が19XX年〜20XX年にしてあるので大丈夫です。 [「日付が1~31までの値であること」ぐらいにして、別なルーチンでチェックする]というのを試してみたいと思います。ありがとうございます。
guest

0

何でも正規表現を使うことを考える人には直接の回答ではありませんが、参考に。
【JavaScript入門】日付の加算・減算方法まとめ(月またぎ/うるう年)

投稿2020/02/14 02:25

Orlofsky

総合スコア16415

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

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

t_t_t_t_t_t

2020/02/14 03:53

参考にさせて頂きます。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問