จะตรวจสอบ DateTime ใน C # ได้อย่างไร?


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.Galvez

2
@ D.Galvez ขอโทษที่ฉันมางานปาร์ตี้ช้า แต่เป็นแนวทางปฏิบัติที่ดีที่สุดในการใส่วงเล็บแม้ว่าจะมีเพียง 1 คำสั่ง? นี่อาจเป็นสถานการณ์ที่ความชอบส่วนบุคคลมีความสำคัญที่สุด - และในกรณีนี้ฉันพบว่าการรวมสิ่งเหล่านี้เข้าด้วยกันค่อนข้างดีเพียงเพื่อให้อ่านง่ายและสม่ำเสมอ
นิค

2
เมื่อ 6 ปีก่อนฉันไม่ค่อยรู้ว่าจะมีการถกเถียงเรื่องวงเล็บ
qui

เป็นไปได้ที่จะย่อการเริ่มต้นตัวแปรด้วย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ชนิดและเป็นเท็จ

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

3
ยินดีต้อนรับสู่ StackOverflow! โปรดดูคำตอบที่ให้ไว้แล้วโดยเฉพาะอย่างยิ่งเมื่อตอบคำถามที่มีอายุมากกว่าสามปีและได้รับคำตอบเรียบร้อยแล้ว คำตอบของคุณถูกครอบคลุมโดยผู้ตอบก่อนหน้านี้แล้ว
Bob Kaufman



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

    }

ฉันไม่กังวลเกี่ยวกับ seporators ในกรณีของฉันเพราะฉันใช้ Masked Text Box แต่ฉันเห็นว่ามันจะมีประโยชน์อย่างไรในสถานการณ์อื่น ๆ ที่ฉันอาจพบกับแอพนี้
Matt

เหตุผลในการใช้สตริง 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" คืนค่าจริงหรือ
"2013/2/31" ส่งกลับเท็จ
http://forums.asp.net/t/1250332.aspx/1
// bool booleanValue = ValidateBirthday ("12:55"); ส่งคืนเท็จ


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
วิธีการส่งคืนผลลัพธ์ของ DateTime.TryParse () แทนที่จะเป็นบล็อก "if" นอกจากนี้ 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
แม้ว่ารหัสนี้จะช่วยแก้ปัญหาได้รวมถึงคำอธิบายว่าทำไมจึงแก้ปัญหานี้ได้จะช่วยปรับปรุงคุณภาพของโพสต์ของคุณได้อย่างแท้จริงและอาจส่งผลให้มีการโหวตเพิ่มขึ้น จำไว้ว่าคุณกำลังตอบคำถามสำหรับผู้อ่านในอนาคตไม่ใช่แค่คนที่ถามตอนนี้ โปรดแก้ไขคำตอบของคุณเพื่อเพิ่มคำอธิบายและระบุข้อ จำกัด และสมมติฐานที่ใช้
Brian

คำถามคือถามวิธีตรวจสอบความถูกต้องstringที่อาจมีหรือไม่มี DateTImeค่า คุณกำลังตรวจสอบว่าค่าที่กำหนด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
คุณต้องตรวจสอบว่าถูกต้องโดยลองจับ ดังนั้นคุณสามารถใช้ try catch เพื่อตรวจสอบตัวแปรทุกประเภทและสร้าง Global Functions ที่ถูกต้องและควบคุมทั้งหมดในโครงการของคุณ ขอแสดงความนับถือ ..... 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.