C#でDateTimeを検証する方法


118

私がこの解決策を考え出したのは私だけではないと思いますが、より良い解決策がある場合は、こちらに投稿してください。私はこの質問をここに残して、後で検索できるようにします。

有効な日付がテキストボックスに入力されたかどうかを確認する必要があり、これが私が思いついたコードです。フォーカスがテキストボックスを離れたときにこれを起動します。

try
{
    DateTime.Parse(startDateTextBox.Text);
}
catch
{
    startDateTextBox.Text = DateTime.Today.ToShortDateString();
}

1
<sarcasm>答えから判断して、私はTryParseを使用するべきだと思います</ sarcasm>すばらしい回答をありがとうございます。私はTryParseについてさえ考えていませんでした
Matt

2
誰かが今日尋ねた場合、「研究が不十分」であると不当に締め切られる、Googleに簡単な質問の例。
live-love

1
これは、特別な機能を使用せずにこれを行う簡単な方法です。< stackoverflow.com/questions/14917203/… >
Zameer


2
DateTimesでの作業は、常に低音の苦痛です。ありがとう
Gonzo345

回答:


269
DateTime.TryParse

これは私がより速く、そして醜いトライ/キャッチを使用する必要がないことを意味します:)

例えば

DateTime temp;
if(DateTime.TryParse(startDateTextBox.Text, out temp))
{
  // Yay :)
}
else
{
  // Aww.. :(
}

2
私が間違っている場合は修正してくださいが、C#では(たとえば、JavaScriptとは対照的に)if / elseブランチで中括弧は必要ありませんか?私を誤解しないでください、私は精査しようとはしていません、それは素晴らしい答えです、そしてそれは私を助けたのでそれを+1していますが、すでに投稿された回答を表示するときに新しい将来のユーザーがどのようにいるかわからないので、これは考えました、これそれらを混同する可能性があります。もちろん、C#で中かっこで問題が発生している場合、この質問はあなたの心配の中で最も少ないでしょう...
VoidKing

2
@VoidKing中括弧は正しいですが、そのブロックにステートメントが1つしかない場合は、中括弧を使用する必要はありません。これは他のいくつかの言語にも当てはまりますが、これが新しいコーダーに誤解を招く可能性があることがわかります。
D.ガルベス2014年

2
@ D.Galvezパーティーに来てすみませんが、ステートメントが1つしかない場合でも角かっこを含めるのがベストプラクティスですか。これは、個人的な好みが最も重要な状況である可能性があります。その場合、読みやすさと一貫性の観点からそれらを含めると非常に便利だと思います。
Nick 14

2
6年前、括弧についてのそのような議論が起こることはほとんど知りませんでした。
2014

if(DateTime.TryParse(startDateTextBox.Text, out var temp)):)で変数の初期化を短くすることが可能です
Alexandre Daubricourt

61

フロー制御に例外を使用しないでください。DateTime.TryParseおよびDateTime.TryParseExactを使用します。個人的には、特定の形式のTryParseExactを好みますが、TryParseの方が優れている場合があると思います。元のコードに基づく使用例:

DateTime value;
if (!DateTime.TryParse(startDateTextBox.Text, out value))
{
    startDateTextox.Text = DateTime.Today.ToShortDateString();
}

このアプローチを選ぶ理由:

  • より明確なコード(それが何をしたいかを示しています)
  • 例外をキャッチして飲み込むよりもパフォーマンスが良い
  • これは例外を不適切にキャッチしません-たとえばOutOfMemoryException、ThreadInterruptedException。(現在のコードは、関連する例外をキャッチするだけでこれを回避するように修正できますが、TryParseを使用する方が良いでしょう。)

24

文字列をDateTime型に変換できる場合はtrueを返し、それ以外の場合はfalse を返すソリューションの別のバリエーションを次に示します。

public static bool IsDateTime(string txtDate)
{
    DateTime tempDate;
    return DateTime.TryParse(txtDate, out tempDate);
}

3
StackOverflowへようこそ!すでに提供されている回答を確認してください。特に、3年以上経過しており、正常に回答された質問に回答する場合は特にそうです。あなたの回答は以前の回答者によってすでにカバーされています。
ボブカウフマン



3

使用に関する問題DateTime.TryParseは、セパレーターなしで入力された日付の非常に一般的なデータ入力ユースケースをサポートしないこと011508です。

これをサポートする方法の例を次に示します。(これは私が構築しているフレームワークからのものであるため、その署名は少し奇妙ですが、コアロジックは使用できるはずです)。

    private static readonly Regex ShortDate = new Regex(@"^\d{6}$");
    private static readonly Regex LongDate = new Regex(@"^\d{8}$");

    public object Parse(object value, out string message)
    {
        msg = null;
        string s = value.ToString().Trim();
        if (s.Trim() == "")
        {
            return null;
        }
        else
        {
            if (ShortDate.Match(s).Success)
            {
                s = s.Substring(0, 2) + "/" + s.Substring(2, 2) + "/" + s.Substring(4, 2);
            }
            if (LongDate.Match(s).Success)
            {
                s = s.Substring(0, 2) + "/" + s.Substring(2, 2) + "/" + s.Substring(4, 4);
            }
            DateTime d = DateTime.MinValue;
            if (DateTime.TryParse(s, out d))
            {
                return d;
            }
            else
            {
                message = String.Format("\"{0}\" is not a valid date.", s);
                return null;
            }
        }

    }

マスクされたテキストボックスを使用しているので、私の場合はセパレーターについて心配していませんが、このアプリで発生する可能性がある他の状況でそれがどのように役立つかを確認できます。
マット、

セパレータなしのDateTime文字列を使用する理由は何ですか?
Sergei Kovalenko

1
    protected bool ValidateBirthday(String date)
    {
        DateTime Temp;

        if (DateTime.TryParse(date, out Temp) == true &&
      Temp.Hour == 0 &&
      Temp.Minute == 0 &&
      Temp.Second == 0 &&
      Temp.Millisecond == 0 &&
      Temp > DateTime.MinValue)
            return true;
        else
            return false;
    }

//入力文字列が短い日付形式であると仮定します。
たとえば、「2013/7/5」はtrueを返し、
「2013/2/31」はfalseを返します。
http://forums.asp.net/t/1250332.aspx/1
// bool booleanValue = ValidateBirthday( "12:55"); falseを返します


1
private void btnEnter_Click(object sender, EventArgs e)
{
    maskedTextBox1.Mask = "00/00/0000";
    maskedTextBox1.ValidatingType = typeof(System.DateTime);
    //if (!IsValidDOB(maskedTextBox1.Text)) 
    if (!ValidateBirthday(maskedTextBox1.Text))
        MessageBox.Show(" Not Valid");
    else
        MessageBox.Show("Valid");
}
// check date format dd/mm/yyyy. but not if year < 1 or > 2013.
public static bool IsValidDOB(string dob)
{ 
    DateTime temp;
    if (DateTime.TryParse(dob, out temp))
        return (true);
    else 
        return (false);
}
// checks date format dd/mm/yyyy and year > 1900!.
protected bool ValidateBirthday(String date)
{
    DateTime Temp;
    if (DateTime.TryParse(date, out Temp) == true &&
        Temp.Year > 1900 &&
       // Temp.Hour == 0 && Temp.Minute == 0 &&
        //Temp.Second == 0 && Temp.Millisecond == 0 &&
        Temp > DateTime.MinValue)
        return (true);
    else
        return (false);
}

1

すべての回答はかなり素晴らしいですが、単一の関数を使用したい場合は、これでうまくいくかもしれません。

private bool validateTime(string dateInString)
{
    DateTime temp;
    if (DateTime.TryParse(dateInString, out temp))
    {
       return true;
    }
    return false;
}

1
「if」ブロックの代わりにDateTime.TryParse()の結果を返すのはどうですか?また、IDEは、使用されていないtempについて文句を言うでしょう。これは、関数呼び出し内で直接「out DateTime temp」として宣言できます。
Sergei Kovalenko

0

DateTime特定のフォーマットを定義することもできますCultureInfo

public static bool IsDateTime(string tempDate)
{
    DateTime fromDateValue;
    var formats = new[] { "MM/dd/yyyy", "dd/MM/yyyy h:mm:ss", "MM/dd/yyyy hh:mm tt", "yyyy'-'MM'-'dd'T'HH':'mm':'ss" };
    return DateTime.TryParseExact(tempDate, formats, System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.None, out fromDateValue);
}

-1
protected static bool CheckDate(DateTime date)
{
    if(new DateTime() == date)      
        return false;       
    else        
        return true;        
} 

2
このコードは問題を解決する可能性がありますが、これが問題を解決する方法と理由の説明含めると、投稿の品質が向上し、おそらく投票数が増えることになります。あなたが今尋ねている人だけでなく、あなたが将来の読者のための質問に答えていることを忘れないでください。回答を編集して説明を追加し、適用される制限と前提を示してください。
ブライアン

問題はstringDateTIme値を含む場合と含まない場合があるを検証する方法を尋ねること です。DateTime指定された値にデフォルト値(に対応0001-01-01T00:00:00.0000000)があるかどうかを確認しています。これはどのように質問に答えますか?
dbc

-3
DateTime temp;
try
{
    temp = Convert.ToDateTime(grd.Rows[e.RowIndex].Cells["dateg"].Value);
    grd.Rows[e.RowIndex].Cells["dateg"].Value = temp.ToString("yyyy/MM/dd");
}
catch 
{   
    MessageBox.Show("Sorry The date not valid", "Error", MessageBoxButtons.OK, MessageBoxIcon.Stop,MessageBoxDefaultButton.Button1,MessageBoxOptions .RightAlign);
    grd.Rows[e.RowIndex].Cells["dateg"].Value = null;
}

1
Uはtry catchによって有効かどうかを確認する必要があります。したがって、Uは、try catchを使用してすべてのタイプの変数をチェックし、有効なグローバル関数を作成して、プロジェクト内のすべてを制御できます。よろしくお願いします..... Ashraf khalifah
Ashraf Khalifah

-3
DateTime temp;
try
{
    temp = Convert.ToDateTime(date);
    date = temp.ToString("yyyy/MM/dd");
}
catch 
{
    MessageBox.Show("Sorry The date not valid", "Error", MessageBoxButtons.OK, MessageBoxIcon.Stop,MessageBoxDefaultButton.Button1,MessageBoxOptions .RightAlign);
    date = null;
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.