2011-08-14 6 views

Odpowiedz

23

Nie jestem pewien, czy jestem tam zbyt pedantyczny, ale DateTime.TryParse sprawdzi, czy wartość jest poprawna Obiekt DateTime. OP zapytał o weryfikację wartości przed wstawieniem do datetime serwera SQL. Zakres dopuszczalnych wartości dla SQL Server datetime to "1 stycznia 1753, do 31 grudnia 9999". Nie dotyczy to obiektów DateTime .NET. Ten skrypt przypisuje wartość "1/1/0001 12:00:00 AM" do badDateTime i pomyślnie analizuje.

DateTime d = DateTime.MinValue; 
string badDateTime = DateTime.MinValue.ToString(); 
Console.WriteLine(badDateTime); 
DateTime.TryParse(badDateTime, out d); 

Jeśli jednak próbowali zapisać, że do pola datetime, to nie z „Konwersja typu danych varchar do typu danych datetime spowodowało wartości out-of-Range”.

Komentator zapytał, dlaczego użyłem 997 dla milisekund, jest to objęte SQL Server 2008 and milliseconds, ale zapisując ci kliknięcie, 997 jest największą wartością, jaką możesz przechowywać w typie datetime. 998 zostanie zaokrąglona do 1 sekundy z 000 milisekund

/// <summary> 
    /// An initial pass at a method to verify whether a value is 
    /// kosher for SQL Server datetime 
    /// </summary> 
    /// <param name="someval">A date string that may parse</param> 
    /// <returns>true if the parameter is valid for SQL Sever datetime</returns> 
    static bool IsValidSqlDatetime(string someval) 
    { 
     bool valid = false; 
     DateTime testDate = DateTime.MinValue; 
     DateTime minDateTime = DateTime.MaxValue; 
     DateTime maxDateTime = DateTime.MinValue; 

     minDateTime = new DateTime(1753, 1, 1); 
     maxDateTime = new DateTime(9999, 12, 31, 23, 59, 59, 997); 

     if (DateTime.TryParse(someval, out testDate)) 
     { 
      if (testDate >= minDateTime && testDate <= maxDateTime) 
      { 
       valid = true; 
      } 
     } 

     return valid; 
    } 

Prawdopodobnie jest to lepsze podejście, jak to będzie próbował rzucić obiekt DateTime do rzeczywistej sql datetime typu danych


/// <summary> 
    /// An better method to verify whether a value is 
    /// kosher for SQL Server datetime. This uses the native library 
    /// for checking range values 
    /// </summary> 
    /// <param name="someval">A date string that may parse</param> 
    /// <returns>true if the parameter is valid for SQL Sever datetime</returns> 
    static bool IsValidSqlDateTimeNative(string someval) 
    { 
     bool valid = false; 
     DateTime testDate = DateTime.MinValue; 
     System.Data.SqlTypes.SqlDateTime sdt; 
     if (DateTime.TryParse(someval, out testDate)) 
     { 
      try 
      { 
       // take advantage of the native conversion 
       sdt = new System.Data.SqlTypes.SqlDateTime(testDate); 
       valid = true; 
      } 
      catch (System.Data.SqlTypes.SqlTypeException ex) 
      { 

       // no need to do anything, this is the expected out of range error 
      } 
     } 

     return valid; 
    } 
+0

Tak, masz rację. Szukam rozwiązania, aby upewnić się, że ciąg, który mam jako DateTime teraz będzie insterted w polu Datetime w tabeli bez żadnego błędu. – MichaelVerossa

+0

Edytowane, aby dodać prostą metodę, która sprawdzi, czy wartości są w zasięgu. Próbowanie drugiego podejścia może być mniej podatne na błędy – billinkc

+0

Spróbuję twojej metody! Dziękuję, billinkc! – MichaelVerossa

1

Jeśli wspomnieć o walidacji po stronie serwera w danej dziedzinie DateTime, użyj DateTime.TryParse. Szybki i brudny przykładem będzie

DateTime dateValue; 
string dateString = "05/01/2009 14:57:32.8"; 
if (DateTime.TryParse(dateString, out dateValue)) 
{ 
    // valid date comes here. 
    // use dateValue for this 
} 
else 
{ 
    // valid date comes here 
} 
1

DateTime.TryParse jest najlepszy weryfikator

DateTime temp; 
if(DateTime.TryParse(txtDate.Text, out temp)) 
//Works 
else 
// Doesnt work 
+0

nie w tym przypadku. Każdy SQLDatetime jest prawidłową datetime .NET, ale nie na odwrót. – bjoern

1

można udostępnić bt Więcej informacji na temat gdzie wartość datetime pochodzi; formularz internetowy? Mogłeś po prostu dodać CompareValidator następująco

<asp:CompareValidator ID="CompareValidator1" runat="server" 
      ControlToValidate="txtDate" 
      Type="Date" 
      ErrorMessage="CompareValidator"> 
</asp:CompareValidator> 
+0

+0

http://stackoverflow.com/editing-help – naveen

+1

Dzięki Naveen, okazało się trochę bólu głowy :) –

1

Można użyć SqlCommand z Parametter aby zapobiec SQL injection

Dla examplae:

SqlCommand cmn = new SqlCommand("UPDATE table SET date = @Date "); 
// cmn set Here.... 
cmn.Parameters.Add("@Date",SqlDbType.DateTime).Value = dateTimeObj; 

i inne (s), można zobaczyć w MSDN

2

To kolejne podejście do odpowiedzi billinkc. Jednak w tej metodzie właściwość .Value wartości min/max jest używana w celu uniknięcia analizy składniowej i próby/catch. Ktoś wspomniał, że chce upewnić się, że wstawia poprawną datę do SQL Server. Tak więc podjąłem metodę zwracania daty, która jest ważna dla SQL Server. Można to łatwo zmienić na metodę boolowską, która sprawdza, czy dataToVerify jest prawidłową datą SQL Server.

protected DateTime EnsureValidDatabaseDate(DateTime dateToVerify) 
{ 
    if (dateToVerify < System.Data.SqlTypes.SqlDateTime.MinValue.**Value**) 
    { 
     return System.Data.SqlTypes.SqlDateTime.MinValue.Value; 
    } 
    else if (dateToVerify > System.Data.SqlTypes.SqlDateTime.MaxValue.**Value**) 
    { 
     return System.Data.SqlTypes.SqlDateTime.MaxValue.Value; 
    } 
    else 
    { 
     return dateToVerify; 
    } 
} 
12

Spróbuj bez hardcoding sql wartość datetime:

public bool IsValidSqlDateTime(DateTime? dateTime) 
    { 
     if (dateTime == null) return true; 

     DateTime minValue = DateTime.Parse(System.Data.SqlTypes.SqlDateTime.MinValue.ToString()); 
     DateTime maxValue = DateTime.Parse(System.Data.SqlTypes.SqlDateTime.MaxValue.ToString()); 

     if (minValue > dateTime.Value || maxValue < dateTime.Value) 
      return false; 

     return true; 
    } 
+1

Można również użyć operatora rzutowania jawnego zdefiniowanego w strukturze SqlDateTime; zamiast analizowania reprezentacji napisów: 'var minValue = (DateTime) System.Data.SqlTypes.SqlDateTime.MinValue;' – Styxxy

2
<asp:RangeValidator runat="server" ID="rgvalDate" ControlToValidate="txtDate" Text="[Invalid]" Type="Date" MinimumValue="1/1/1753" MaximumValue="12/31/9999" /> 

LUB

niestandardowy walidator:

protected void cvalDOB_ServerValidate(object sender, ServerValidateEventArgs e) 
    { 
     e.IsValid = IsValidSqlDateTime(e.Value); 
    } 

    public static bool IsValidSqlDateTime(object Date) 
    { 
     try 
     { 
      System.Data.SqlTypes.SqlDateTime.Parse(Date.ToString()); 
      return true; 
     } 
     catch 
     { 
      return false; 
     } 
    }