Làm thế nào để xác thực DateTime trong C #?


118

Tôi nghi ngờ tôi là người duy nhất đưa ra giải pháp này, nhưng nếu bạn có giải pháp tốt hơn, vui lòng đăng nó ở đây. Tôi chỉ đơn giản là muốn để câu hỏi này ở đây để tôi và những người khác có thể tìm kiếm nó sau.

Tôi cần biết liệu ngày hợp lệ đã được nhập vào hộp văn bản hay chưa và đây là mã mà tôi nghĩ ra. Tôi kích hoạt điều này khi tiêu điểm rời khỏi hộp văn bản.

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

1
<sarcasm> đánh giá câu trả lời, tôi nghĩ tôi nên sử dụng TryParse </sarcasm> Cảm ơn vì những câu trả lời tuyệt vời. Tôi thậm chí đã không nghĩ về TryParse
Matt

2
Một ví dụ về một câu hỏi dễ dàng để google mà nếu ai đó hỏi ngày hôm nay sẽ bị đóng cửa không công bằng vì "không đủ nghiên cứu".
live-love vào

1
đây là một cách dễ dàng để làm điều này mà không cần sử dụng bất kỳ chức năng đặc biệt: < stackoverflow.com/questions/14917203/... >
Zameer


2
Làm việc với DateTimes luôn là một khó khăn trong âm trầm. Cảm ơn
Gonzo345

Câu trả lời:


269
DateTime.TryParse

Tôi tin rằng điều này là nhanh hơn và nó có nghĩa là bạn không phải sử dụng thử / bắt xấu xí :)

ví dụ

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

2
Hãy sửa cho tôi nếu tôi sai, nhưng trong C # (trái ngược với JavaScript) không phải một nhánh if / else yêu cầu dấu ngoặc nhọn? Đừng hiểu sai ý tôi, tôi không cố gắng xem xét kỹ lưỡng, đó là một câu trả lời tuyệt vời và tôi đã +1 nó vì nó giúp ích cho tôi, nhưng chỉ nghĩ vì bạn không bao giờ biết người dùng mới trong tương lai như thế nào khi xem các câu trả lời đã đăng, điều này có thể khiến họ nhầm lẫn. Tất nhiên, nếu bạn đang gặp rắc rối với dấu ngoặc nhọn trong C #, câu hỏi này sẽ là nhỏ nhất của lo lắng của bạn ...
VoidKing

2
@VoidKing Bạn nói đúng về dấu ngoặc nhọn nhưng nếu bạn chỉ có 1 câu lệnh trong khối đó thì bạn không cần phải sử dụng chúng. Điều này cũng áp dụng trong một số ngôn ngữ khác nhưng tôi có thể thấy điều này có thể gây hiểu lầm cho các lập trình viên mới hơn như thế nào.
D.Galvez

2
@ D.Galvez Xin lỗi vì tôi đến dự tiệc muộn, nhưng cách tốt nhất là đưa vào dấu ngoặc đơn ngay cả khi chỉ có 1 câu lệnh? Đây có thể chỉ là một tình huống mà sở thích cá nhân là quan trọng nhất - và trong trường hợp đó, tôi thấy việc bao gồm chúng là khá tốt chỉ đơn giản là dễ đọc và nhất quán.
Nick

2
Cách đây 6 năm tôi ít biết rằng một cuộc tranh luận như vậy về dấu ngoặc sẽ xảy ra.
qui

Có thể rút ngắn thời biến khởi tạo với if(DateTime.TryParse(startDateTextBox.Text, out var temp)):)
Alexandre Daubricourt

61

Không sử dụng ngoại lệ để kiểm soát luồng. Sử dụng DateTime.TryParseDateTime.TryParseExact . Cá nhân tôi thích TryParseExact với một định dạng cụ thể, nhưng tôi đoán rằng có những lúc TryParse tốt hơn. Ví dụ sử dụng dựa trên mã gốc của bạn:

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

Lý do thích cách tiếp cận này:

  • Mã rõ ràng hơn (nó cho biết nó muốn làm gì)
  • Hiệu suất tốt hơn so với bắt và nuốt các ngoại lệ
  • Điều này không bắt các ngoại lệ không thích hợp - ví dụ: OutOfMemoryException, ThreadInterruptException. (Mã hiện tại của bạn có thể được sửa để tránh điều này bằng cách chỉ bắt ngoại lệ có liên quan, nhưng sử dụng TryParse sẽ vẫn tốt hơn.)

24

Đây là một biến thể khác của giải pháp trả về true nếu chuỗi có thể được chuyển đổi thành một DateTimekiểu và false nếu không.

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

3
Chào mừng bạn đến với StackOverflow! Vui lòng xem các câu trả lời đã được cung cấp, đặc biệt là khi trả lời một câu hỏi hơn ba năm tuổi và đã được trả lời thành công. Câu trả lời của bạn đã được bao gồm bởi những người trả lời trước.
Bob Kaufman



3

Một vấn đề với việc sử dụng DateTime.TryParselà nó không hỗ trợ trường hợp sử dụng nhập dữ liệu rất phổ biến của ngày được nhập mà không có dấu phân tách, ví dụ 011508.

Đây là một ví dụ về cách hỗ trợ điều này. (Đây là từ một khuôn khổ mà tôi đang xây dựng, vì vậy chữ ký của nó hơi kỳ lạ, nhưng logic cốt lõi sẽ có thể sử dụng được):

    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;
            }
        }

    }

Tôi không lo lắng về người phân tách trong trường hợp của mình vì tôi đang sử dụng Hộp văn bản có mặt nạ, nhưng tôi có thể thấy điều đó sẽ hữu ích như thế nào trong các tình huống khác mà tôi có thể gặp phải với ứng dụng này.
Matt

Lý do sử dụng chuỗi DateTime không có dấu phân tách là gì?
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;
    }

// giả sử chuỗi đầu vào đó là định dạng ngày ngắn.
ví dụ: "2013/7/5" trả về true hoặc
"2013/2/31" trả về false.
http://forums.asp.net/t/1250332.aspx/1
// bool booleanValue = ValidateBirthday ("12:55"); trả về sai


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

Tất cả các Câu trả lời đều Khá tuyệt vời nhưng nếu bạn muốn sử dụng một chức năng duy nhất, điều này có thể hoạt động.

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

1
Làm thế nào về việc trả về kết quả của DateTime.TryParse () thay vì khối "if"? Ngoài ra, IDE của bạn sẽ phàn nàn về tạm thời không bao giờ được sử dụng, mà bạn có thể khai báo bên trong lệnh gọi hàm trực tiếp là "tạm thời ra DateTime".
Sergei Kovalenko

0

Bạn cũng có thể xác định định DateTimedạng cho mộtCultureInfo

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
Mặc dù mã này có thể giải quyết câu hỏi, bao gồm giải thích về cách thức và lý do tại sao điều này giải quyết vấn đề sẽ thực sự giúp cải thiện chất lượng bài đăng của bạn và có thể dẫn đến nhiều phiếu bầu hơn. Hãy nhớ rằng bạn đang trả lời câu hỏi cho độc giả trong tương lai, không chỉ người hỏi bây giờ. Vui lòng chỉnh sửa câu trả lời của bạn để thêm giải thích và đưa ra dấu hiệu về những giới hạn và giả định nào được áp dụng.
Brian

Câu hỏi đặt ra là làm thế nào để xác thực stringmột DateTImegiá trị có thể chứa hoặc không . Bạn đang kiểm tra xem liệu một DateTimegiá trị đã cho có giá trị mặc định (tương ứng với 0001-01-01T00:00:00.0000000) hay không. Làm thế nào để trả lời câu hỏi này?
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
Bạn phải kiểm tra tính hợp lệ bằng cách thử bắt. Vì vậy, bạn có thể sử dụng try catch để kiểm tra tất cả các biến loại và tạo các Hàm toàn cầu hợp lệ và kiểm soát tất cả trong dự án của bạn. lời chúc mừng tốt đẹp nhất ..... 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;
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.