web-dev-qa-db-de.com

DateTime.MinValue- und SqlDateTime-Überlauf

Ich möchte txtBirthDate nicht validieren, also DateTime.MinValue in der Datenbank übergeben.

Mein Code: 

 if (txtBirthDate.Text == string.Empty)
    objinfo.BirthDate = DateTime.MinValue;
 else
     objinfo.BirthDate =  DateTime.Parse(txtBirthDate.Text);

DateTime.MinValue return Date = {1/1/0001 12:00:00 AM}

Ich habe einen SQL-Fehler erhalten:

SqlDateTime-Überlauf. Muss zwischen dem 01.01.1753 12:00:00 und dem 31.12.99999 23:59:59 Uhr liegen.

Ich verstehe es, aber ich verstehe nicht, warum DateTime.MinValue eine ungültige Datumszeit zurückgibt, die nicht in die Datenbank eingefügt werden kann.

45
Shree

Verwenden Sie DateTime.MinValue grundsätzlich nicht, um einen fehlenden Wert darzustellen. Sie kann nicht verwendet DateTime.MinValue in einem SQL Server DateTime-Feld, da SQL Server einen Mindestwert von 1753 hat.

Machen Sie stattdessen Ihre BirthDate-Eigenschaft zu einem Nullable<DateTime> (aka DateTime?) und setzen Sie ihn auf null, wenn Sie keinen Wert haben. Stellen Sie außerdem sicher, dass Ihr Datenbankfeld nullwertfähig ist. Dann müssen Sie nur sicherstellen, dass null als NULL-Wert in der Datenbank endet. Wie Sie das genau machen, hängt von Ihrem Datenzugriff ab, von dem Sie uns nichts erzählt haben.

76
Jon Skeet

Vermeiden Sie es sehr einfach, DateTime.MinValue zu verwenden, stattdessen System.Data.SqlTypes.SqlDateTime.MinValue.

69
Sankar M

Obwohl es sich um eine alte Frage handelt, ist eine andere Lösung die Verwendung von datetime2 für die Datenbankspalte . MSDN Link

9
Abhay Kumar

Hier ist, was Sie tun können. Es gibt viele Möglichkeiten, dies zu erreichen. 

DateTime? d = null;    
if (txtBirthDate.Text == string.Empty)
    objinfo.BirthDate = d;
else
    objinfo.BirthDate =  DateTime.Parse(txtBirthDate.Text);

Hinweis: Dies funktioniert nur, wenn Ihre Datenbank-Datetime-Spalte Null zulassen ist. Andernfalls können Sie einen Standard-Mindestwert für DateTime definieren. D.

3
Praveen Nambiar

Ich verwende diese Funktion zum Tryparse

public static bool TryParseSqlDateTime(string someval, DateTimeFormatInfo dateTimeFormats, out DateTime tryDate)
    {
        bool valid = false;
        tryDate = (DateTime)System.Data.SqlTypes.SqlDateTime.MinValue;
        System.Data.SqlTypes.SqlDateTime sdt;
        if (DateTime.TryParse(someval, dateTimeFormats, DateTimeStyles.None, out tryDate))
        {
            try
            {
                sdt = new System.Data.SqlTypes.SqlDateTime(tryDate);
                valid = true;
            }
            catch (System.Data.SqlTypes.SqlTypeException ex)
            {

            }
        }

        return valid;
    }
3
liorlevi1974

Einfach ausgedrückt: nicht Verwenden Sie DateTime.MinVaue als Standardwert.

Es gibt ein paar verschiedene MinValues, abhängig von der Umgebung, in der Sie sich befinden.

Ich hatte einmal ein Projekt, bei dem ich ein Windows CE-Projekt implementierte. Ich verwendete den DateTime.MinValue (Year 0001) des Frameworks, die Datenbank MinValue (1753) und ein UI-Steuerelement DateTimePicker (ich glaube, es war 1970). Es gab also mindestens 3 verschiedene MinValues ​​, die zu merkwürdigem Verhalten und unerwarteten Ergebnissen führten. (Und ich glaube, dass es sogar eine vierte (!) Version gab, ich erinnere mich einfach nicht, woher sie kam.).

Verwenden Sie ein nullfähiges Datenbankfeld und ändern Sie stattdessen Ihren Wert in einen Nullable<DateTime>. Wenn kein gültiger Wert in Ihrem Code vorhanden ist, sollte nicht auch ein Wert in der Datenbank vorhanden sein. :-)

2
Jens H

Von MSDN:

Datums- und Zeitangaben vom 1. Januar 1753 bis 31. Dezember 9999 mit einem Genauigkeit von einem Dreihundertstel oder 3,33 Millisekunden. Werte werden auf Inkremente von, 000, 0,003 oder 0,007 Millisekunden gerundet. Gelagert als zwei 4-Byte-Ganzzahlen. Die ersten 4 Bytes speichern die Anzahl der Tage vor oder nach dem Basisdatum, 1. Januar 1900. Das Basisdatum ist das Referenzdatum des Systems. Werte für datetime vor dem 1. Januar 1753 sind nicht erlaubt. Die anderen 4 Bytes speichern die Uhrzeit dargestellt als Anzahl Millisekunden nach Mitternacht. Sekunden haben ein gültiger Bereich von 0–59.

SQL verwendet ein anderes System als C # für DateTime-Werte.

Sie können Ihren MinValue als Sentinel-Wert verwenden - und wenn es MinValue ist - geben Sie null in Ihr Objekt ein (und speichern Sie das Datum als nullwertfähig in der Datenbank).

if(date == dateTime.Minvalue)
    objinfo.BirthDate = null;
2
Dave Bish

Nun ... es ist ziemlich einfach, ein SQL-Min-Datum zu erhalten

DateTime sqlMinDateAsNetDateTime = System.Data.SqlTypes.SqlDateTime.MinValue.Value;
0
Richard Barker

Wenn Sie DATETIME2 verwenden, müssen Sie möglicherweise feststellen, dass Sie den Parameter speziell als DATETIME2 übergeben müssen. Andernfalls wird er möglicherweise in DATETIME konvertiert.

command.Parameters.Add("@FirstRegistration",SqlDbType.DateTime2).Value = installation.FirstRegistration;
0
David Homer