English 中文(简体)
Validate date textbox
原标题:

I m using the following code to check if a valid date has been typed into a textbox:

public bool ValidateDate(Control ctrl)
{
    if (!string.IsNullOrEmpty(ctrl.Text))
    {
        DateTime value;
        if (!DateTime.TryParse(ctrl.Text, out value))
        {
            return false;
        }
    }
    return true;
}


private void txtStartDate_Validating(object sender, CancelEventArgs e)
{
    if (Utils.ValidateDate(txtStartDate))
    {
        errorProvider.SetError(txtStartDate, "");
    }
    else
    {
        errorProvider.SetError(txtStartDate, "* Invalid Date");
        e.Cancel = true;
    }
}

This works fine for dates that are entered m/d/yy, m/d/yyyy, mm/dd/yy, mm/dd/yyyy. If a user enters in a date such as "11/17" this will evaluate to a valid date, but, unfortunately, I only want dates that have all three date parts.

Is there an easy way to do this? I was thinking something a long the lines of checking if there are 2 "/" in the textbox, but I m sure there is a cleaner way of achieving the desired result.

EDIT: Thanks for all the suggestions everyone! I ended up using the following code which accepts M/d/yyyy and M/d/yy ~

    public bool ValidateDate(Control ctrl)
    {          
        if (!string.IsNullOrEmpty(ctrl.Text))
        {
            string[] formats = {"M/d/yyyy", "M/d/yy"};
            DateTime value;

            if  (!DateTime.TryParseExact(ctrl.Text, formats, new CultureInfo("en-US"), DateTimeStyles.None, out value))
            {
                return false;
            }                
        }
        return true;
    }
最佳回答

The DateTime.TryParseExact(..) function does allow you to parse a date using a specific date format (for example, "mm/dd/yyyy"). However, if you want to be flexible on the number of digits in the year, then a regex might be a better choice.

问题回答

You could try using regular expressions:

Regex dateRegExp = new Regex("^(((0?[1-9]|[12]d|3[01])[.-/](0?[13578]|1[02])[.-/]((1[6-9]|[2-9]d)?d{2}|d))|((0?[1-9]|[12]d|30)[.-/](0?[13456789]|1[012])[.-/]((1[6-9]|[2-9]d)?d{2}|d))|((0?[1-9]|1d|2[0-8])[.-/]0?2[.-/]((1[6-9]|[2-9]d)?d{2}|d))|(29[.-/]0?2[.-/]((1[6-9]|[2-9]d)?(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00)|00|[048])))$");

Match m = dateRegExp.Match(dateString);

if (m.Success) {
    //Valid Date 
}
else
{

    //No soup for you, 1 year 
}

(I "borrowed" the regexp from here: RegExpLib)

Create a regular expression that matches a date pattern with all 3 components and use that to validate instead of DateTime.TryParse.

Here is a sample bit of code:

    if (Regex.IsMatch(ctrl.Text, @"(0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])[- /.](19|20)dd"))
        {
            //....
        }

You could use the MaskedTextBox, which is a little more user friendly and will do the validation for you:

private void Form1_Load(object sender, EventArgs e)
{
    maskedTextBox1.Mask = "00/00/0000";
    maskedTextBox1.ValidatingType = typeof(System.DateTime);
}




相关问题
Bring window to foreground after Mutex fails

I was wondering if someone can tell me what would be the best way to bring my application to the foreground if a mutex was not able to be created for a new instance. E.g.: Application X is running ...

How to start WinForm app minimized to tray?

I ve successfully created an app that minimizes to the tray using a NotifyIcon. When the form is manually closed it is successfully hidden from the desktop, taskbar, and alt-tab. The problem occurs ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...

Handle DataTable.DataRow cell change event

I have a DataTable that has several DataColumns and DataRow. Now i would like to handle an event when cell of this DataRow is changed. How to do this in c#?

Apparent Memory Leak in DataGridView

How do you force a DataGridView to release its reference to a bound DataSet? We have a rather large dataset being displayed in a DataGridView and noticed that resources were not being freed after the ...

ALT Key Shortcuts Hidden

I am using VS2008 and creating forms. By default, the underscore of the character in a textbox when using an ampersand is not shown when I run the application. ex. "&Goto Here" is not ...

WPF-XAML window in Winforms Application

I have a Winforms application coded in VS C# 2008 and want to insert a WPF window into the window pane of Winforms application. Could you explain me how this is done.

热门标签