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

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

新規登録して質問してみよう
ただいま回答率
85.50%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

SQL Server

SQL Serverはマイクロソフトのリレーショナルデータベース管理システムです。データマイニングや多次元解析など、ビジネスインテリジェンスのための機能が備わっています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Q&A

解決済

1回答

7149閲覧

SQLでの生年月日の登録

退会済みユーザー

退会済みユーザー

総合スコア0

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

SQL Server

SQL Serverはマイクロソフトのリレーショナルデータベース管理システムです。データマイニングや多次元解析など、ビジネスインテリジェンスのための機能が備わっています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

0グッド

0クリップ

投稿2018/03/15 04:12

前提・実現したいこと

visual studio 2017 c#を用いて
生年月日と年齢をSQL server Management studio 17に
登録できるシステムを作っています。

イメージ説明
イメージ説明

発生している問題・エラーメッセージ

1.生年月日の値を空白で、計算ボタンをクリックすると
"生年月日を正しく入力してください"とメッセージボックスが表示されるようにコードを書いているのですが
ありえない日付や月日だけ(例:1999/99/99、1986//)を入力してクリックすると、文字列は有効なDateTimeではありません
とエラーが発生します。
どのようなコードで対処すればよろしいでしょうか?

2.初期表示設定___/_/_/のMaskedTextBoxを使っています。
SQL server Management Studioと連携させて個人の生年月日をデータベース登録をしているのですが、(データ型はdate)
何も入力しないで登録すると/スラッシュがどうも邪魔をしているのか(?)
文字列から日付と時刻、またはそのいずれかへの変換中に、変換が失敗しました。とエラーが発生します。
なにか対処法はありますでしょうか?
MaskedTextBoxもしくはTextBoxは必ず使いたいと思っています。

年齢計算のコードも計算はできるのですが、正直これで合っているのかわかりません。
訂正あればよろしくお願いいたします。

生年月日のMaskedTextBox・・・MtxtBirthDay
年齢のTextBox・・・TxtAge
年齢計算ボタン・・・ButtonAgeCal

該当のソースコード

C#

1コード 2private void ButtonAgeCal_Click(object sender, EventArgs e) 3{ 4 // 生年月日が正しく入力されていれば年齢計算 5   if (MtxtBirthDay.Text.StartsWith(" ")) 6   { 7    MessageBox.Show("生年月日を正しく入力してください"); 8   } 9   else 10   { 11   DateTime BD = DateTime.Parse(MtxtBirthDay.Text); 12   int age = DateTime.Today.Year - BD.Year; 13 14   if (BD > DateTime.Today.AddYears(-age)) age--; 15 16   TxtAge.Text = age.ToString(); 17   } 18} 19

試したこと

補足情報(FW/ツールのバージョンなど)

初心者で拙い文章ですが
よろしくお願いいたします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

DateTime.Parse() は、日付型として正しくない値を変換しようとするとエラーになります。

DateTime.TryParse() か
DateTime.TryParseExact() 辺りを使えば良いのではないかなと思います。

※あとこれ SQL は関係ないですかね? C# のエラーじゃないでしょうか。


ちなみに、C# が吐いているエラーだとすると、エラー情報の中に line:123 みたいな情報が入っていないでしょうか。
それは 実際にエラーとなっている行番号なので、それを見るとどのファイルの何行目でエラーになっているかが分かります。
今回のエラーだと DateTime.Parse() をしている箇所を指しているのではないかと思います。

実際にエラーとなっている行を特定できると、原因を特定しやすくなります。

#追記

MtxtBirthDay.Text からどういう値が取れるのか分からないのですが・・・
yyyy/M/d でしょうか?

とりあえず以下 TryParseExact の使用例を書いてみました。
TryParse の場合も流れは同じになります。

csharp

1private void test() 2{ 3 String mtxtBirthDay = "2018/03/15"; 4 5 DateTime BD; 6 7 if (! DateTime.TryParseExact(mtxtBirthDay, "yyyy/MM/dd", null, System.Globalization.DateTimeStyles.None, out BD)) 8 { 9 System.Diagnostics.Debug.WriteLine("生年月日を正しく入力してください"); 10 } 11 else 12 { 13 int age = DateTime.Today.Year - BD.Year; 14 if (BD > DateTime.Today.AddYears(-age)) age--; 15 16 System.Diagnostics.Debug.WriteLine("[" + age + "]"); 17 } 18}

alg さんも書かれていますが、TryParse (TryParseExact) の戻り値を見て
DateTime 型に変換できる値か出来ない値かを判定します。
なお 変換できる場合は true, できない場合は false が返ります。

TryParse で「DateTime型に変換できる値かどうか」のチェックは出来るので、
MtxtBirthDay.Text.StartsWith(" ")
でのチェックは要らなくなるかなと思います。

単純な日付文字列であれば TryParse で変換できるかな?
たとえば "★2018★ 03-15" みたいな独自の書式の場合は TryParseExact に "★yyyy★ MM-dd" を指定して変換したりします。

なお TryParseExact() の第2引数でフォーマットを指定していますが、
"yyyy/MM/dd" だと "2018/03/15" は変換できますが "2018/3/15" は変換できません。
"yyyy/M/d" だと両方変換できます。
もし日付文字列が "2018-03-05" であれば 書式は "yyyy-MM-dd" とする必要があります。
(この辺は「C# 日付 書式」とかでぐぐると出てきますかね)

投稿2018/03/15 04:28

編集2018/03/15 06:37
sk_3122

総合スコア1126

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

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

退会済みユーザー

退会済みユーザー

2018/03/15 05:47

ご回答ありがとうございます。 DateTime.TryParseの使い方を熟知していないのですが 以下コードです private void ButtonAgeCal_Click(object sender, EventArgs e) { // 生年月日が正しく入力されていれば年齢計算 if (MtxtBirthDay.Text.StartsWith(" ")) { MessageBox.Show("生年月日を正しく入力してください"); } else { DateTime BD; bool res =DateTime.TryParse(MtxtBirthDay.Text,out BD); int age = DateTime.Today.Year - BD.Year; if (BD > DateTime.Today.AddYears(-age)) age--; TxtAge.Text = age.ToString(); } } このようなコードになりますでしょうか?
alg

2018/03/15 05:59

`DateTime.TryParse`で判定した結果を使わないと意味が無いので、こんな感じじゃないでしょうか。 (一部抜粋) ``` DateTime BD; bool res =DateTime.TryParse(MtxtBirthDay.Text,out BD); if (res) { MessageBox.Show("生年月日を正しく入力してください"); } else { int age = DateTime.Today.Year - BD.Year; if (BD > DateTime.Today.AddYears(-age)) age--; TxtAge.Text = age.ToString(); } ```
退会済みユーザー

退会済みユーザー

2018/03/15 06:17

ご返答ありがとうございます。 alg様のコードを拝借しましたが 例えば、1999/09/09と入力すると 生年月日を正しく入力してくださいとメッセージボックスが表示され 1990/_/_/と入力すると、年齢に2017と表示されてしまいます。 また、生年月日を空白入力で登録すると 文字列から日付と時刻、またはそのいずれかへの変換中に、変換が失敗しました。 とまだエラーは治っていない模様でした。
yy_tn

2018/03/15 06:27 編集

TryParseはDateTime形式に変換できるかどうかだけなので 基本的に入力チェックは自分で実装しないとダメですよ。
sk_3122

2018/03/15 06:39

追記しました。
退会済みユーザー

退会済みユーザー

2018/03/15 08:43

sk_3122様 追記ありがとうございます。 初歩的な質問で申し訳ないのですが この場合は私の用いているMaskedTextBox(MtxtBirthDay)のテキスト入力と関連づけるには どのようにすればよいでしょうか?
sk_3122

2018/03/15 09:00

ちなみに私は MaskedTextBox 使った事ないのですが、 MessageBox.Show(MtxtBirthDay.Text) を実行すると何が表示されますか? 文字列的には "1990/_/_/" ですか? "1990/ / /" でしょうか? 正しく入力した場合は? 基本的には ご自身で書いてみた時のように 私のサンプルコードの mtxtBirthDay を MtxtBirthDay.Text に置き換える感じかなと思いますが (mtxtBirthDayは、入力画面までは作ってないので とりあえず MtxtBirthDay.Text の代わりとして string 変数を使っただけです)
sk_3122

2018/03/15 09:06

なお System.Diagnostics.Debug.WriteLine() も、 WebForms (かな?) だと MessageBox.Show() でメッセージを出しますが、 私が C# のコードをテストしたのは ASP.NET のプロジェクトなので MessageBox が無い為上記でコンソールログに出力しています。 (VisualStudio で C#、といっても WebForms とか WPF とか ASP.NET とか 色々種類があります。ASP.NET はブラウザで動くやつ。でも裏で C# が動いている点は同じ。日付文字列の変換なんかはどっちでも同じコードで動きます)
退会済みユーザー

退会済みユーザー

2018/03/15 09:18

できました! ありがとうございます。 勉強になりました。 private void ButtonAgeCal_Click(object sender, EventArgs e) { DateTime BD; if (!DateTime.TryParseExact(MtxtBirthDay.Text, "yyyy/MM/dd", null, System.Globalization.DateTimeStyles.None, out BD)) { MessageBox.Show("生年月日を正しく入力してください"); } else { int age = DateTime.Today.Year - BD.Year; if (BD > DateTime.Today.AddYears(-age)) age--; TxtAge.Text = age.ToString(); } }
sk_3122

2018/03/15 09:22

お疲れ様ですー ^^
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問