C # 'da DateTime Nasıl Doğrulanır?


118

Bu çözümü bulan tek kişinin ben olduğumdan şüpheliyim, ancak daha iyi bir çözümünüz varsa lütfen buraya gönderin. Ben ve diğerleri daha sonra arayabilmemiz için bu soruyu burada bırakmak istiyorum.

Metin kutusuna geçerli bir tarih girilip girilmediğini söylemem gerekiyordu ve bu benim bulduğum koddu. Odak metin kutusundan çıktığında bunu ateşlerim.

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

1
<sarcasm> yanıtlara bakılırsa, TryParse kullanmam gerektiğini düşünüyorum </sarcasm> Harika yanıtlar için teşekkürler arkadaşlar. TryParse'ı düşünmemiştim bile
Matt

2
Bugün birisi sorulduğunda "yeterli araştırma yapılmadığı için" haksız yere kapatılacak olan, Google'a kolay bir soru örneği.
live-love

1
herhangi bir özel işlev kullanmadan bunu yapmanın kolay bir yolu: < stackoverflow.com/questions/14917203/… >
Zameer


2
DateTimes ile çalışmak basta her zaman bir sıkıntıdır. Teşekkürler
Gonzo345

Yanıtlar:


269
DateTime.TryParse

Bunun daha hızlı olduğuna inanıyorum ve bu, çirkin denemeler / yakalamalar kullanmanıza gerek olmadığı anlamına geliyor :)

Örneğin

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

2
Yanılıyorsam düzeltin, ancak C # 'da (JavaScript'in aksine) if / else dalı kaşlı ayraç gerektirmez mi? Beni yanlış anlamayın, incelemeye çalışmıyorum, bu harika bir cevap ve bana yardımcı olduğu için + 1 yapıyorum, ama şimdiye kadar yayınlanan cevapları görüntülerken gelecekteki kullanıcıların nasıl olacağını asla bilemediğiniz için düşündüm. kafalarını karıştırabilir. Elbette, C # 'da küme parantezlerinde sorun yaşıyorsanız, bu soru endişelerinizin en küçüğü olacaktır ...
VoidKing

2
@VoidKing Küme parantezleri konusunda haklısınız, ancak bu blokta sadece 1 ifadeniz varsa bunları kullanmak zorunda değilsiniz. Bu, diğer bazı dillerde de geçerlidir, ancak bunun yeni kodlayıcılar için nasıl yanıltıcı olabileceğini görebiliyorum.
D.Galvez

2
@ D.Galvez Partiye geç geldiğim için özür dilerim, ancak tek bir ifade olsa bile parantezleri eklemek en iyi uygulama mıdır? Bu sadece kişisel tercihin en önemli olduğu bir durum olabilir - ve bu durumda onları dahil etmeyi basitçe okunabilirlik ve tutarlılık açısından oldukça hoş buluyorum .
Nick

2
Parantezler hakkında böyle bir tartışmanın 6 yıl önce olacağını bilmiyordum.
qui

Değişken başlatmayı kısaltmak mümkün if(DateTime.TryParse(startDateTextBox.Text, out var temp)):)
Alexandre Daubricourt

61

Akış kontrolü için istisnalar kullanmayın. DateTime . TryParse ve DateTime . TryParseExact kullanın . Şahsen ben belirli bir formatta TryParseExact'i tercih ederim, ancak TryParse'ın daha iyi olduğu zamanlar olduğunu tahmin ediyorum. Orijinal kodunuza göre örnek kullanım:

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

Bu yaklaşımı tercih etme nedenleri:

  • Daha net kod (ne yapmak istediğini söylüyor)
  • İstisnaları yakalamak ve yutmaktan daha iyi performans
  • Bu, istisnaları uygunsuz bir şekilde yakalamaz - örneğin OutOfMemoryException, ThreadInterruptedException. (Geçerli kodunuz, yalnızca ilgili istisnayı yakalayarak bundan kaçınmak için düzeltilebilir, ancak TryParse kullanmak yine de daha iyi olacaktır.)

24

Dize bir DateTimetüre dönüştürülebiliyorsa true, aksi takdirde false döndüren çözümün başka bir varyasyonu .

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

3
StackOverflow'a hoş geldiniz! Lütfen, özellikle üç yıldan eski olan ve başarıyla yanıtlanmış bir soruya yanıt verirken, önceden verilmiş yanıtlara bakın. Cevabınız zaten önceki yanıtlayanlar tarafından ele alındı.
Bob Kaufman



3

Kullanımla ilgili bir sorun, DateTime.TryParseayırıcılar olmadan girilen tarihlerin çok yaygın veri girişi kullanımını desteklememesidir, örn.011508 .

İşte bunun nasıl destekleneceğine dair bir örnek. (Bu, oluşturduğum bir çerçeveden, bu yüzden imzası biraz tuhaf, ancak temel mantık kullanılabilir olmalı):

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

    }

Benim durumumdaki ayırıcılar için endişelenmiyorum çünkü Maskeli Metin Kutusu kullanıyorum, ancak bu uygulamayla karşılaşabileceğim diğer durumlarda bunun nasıl kullanışlı olacağını görebiliyorum.
Matt

DateTime dizesini ayırıcılar olmadan kullanmanın nedeni nedir?
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;
    }

// girdi dizesinin kısa tarih biçimi olduğunu varsayalım.
örneğin, "2013/7/5" doğru veya
"2013/2/31" yanlış döndürür.
http://forums.asp.net/t/1250332.aspx/1
// bool booleanValue = ValidateBirthday ("12:55"); yanlış döndürür


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üm Yanıtlar Oldukça harika ancak tek bir işlevi kullanmak istiyorsanız bu işe yarayabilir.

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

1
"İf" bloğu yerine DateTime. TryParse () sonucunu döndürmeye ne dersiniz? Ayrıca, IDE'niz hiç kullanılmamış temp'den şikayet eder, bunu işlev çağrısının içinde doğrudan "out DateTime temp" olarak bildirebilirsiniz.
Sergei Kovalenko

0

Ayrıca DateTimebelirli bir format için format tanımlayabilirsiniz.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
Bu kod soruyu çözebilirken, sorunun nasıl ve neden çözüldüğüne dair bir açıklama da dahil olmak üzere , gönderinizin kalitesini artırmaya gerçekten yardımcı olur ve muhtemelen daha fazla oy almanıza neden olur. Sadece şu anda soran kişi için değil, gelecekte okuyucular için soruyu yanıtladığınızı unutmayın. Açıklamalar eklemek ve hangi sınırlamaların ve varsayımların geçerli olduğuna dair bir gösterge vermek için lütfen yanıtınızı düzenleyin .
Brian

Soru, stringbir DateTImedeğer içeren veya içermeyen bir şeyin nasıl doğrulanacağını soruyor . Verilenin DateTimevarsayılan değerlere sahip olup olmadığını kontrol ediyorsunuz (karşılık gelen 0001-01-01T00:00:00.0000000). Bu soruya nasıl cevap veriyor?
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 ile geçerliliğini kontrol etmelisiniz. Böylece U, tüm değişken türlerini kontrol etmek ve geçerli Global Fonksiyonlar yapmak ve projenizdeki hepsini kontrol etmek için try catch kullanabilir. saygılarımla ..... 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;
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.