Unerwünschte Rundung von DateTime in SQL Server

Ich lief in etwas, das scheint seltsam. SQL Server scheint zu sein, die Rundung einige DateTime Werte unangemessen, wenn ich speichern Sie Sie auf datetime Spalten. Ich vermute, ich bin etwas fehlt, aber ich kann nicht finden es. Ich bin mit diesem test gegen den SQL Server 2008 verwenden .NET 4.0. Folgendes sollte illustrieren das Problem:

Habe ich eine Tabelle in SQL Server, den so genannten Zeitstempel. Es hat zwei Spalten:

id - bigint, Identität, PK

timestamp - datetime -

Ich auch einen einfachen test, der das folgende tut:

  1. Wird die aktuelle Zeit, das abschneiden der Wert in Millisekunden-Präzision
  2. Gespeichert, die abgeschnittene Zeit für Timestamps
  3. Abgerufen datetime " - Wert aus der DB und im Vergleich zum original (gekürzt) DateTime-Objekt.
public static void RoundTest()
{
    DateTime preTruncation = DateTime.UtcNow;
    DateTime truncated = preTruncation.TruncateToMilliseconds();

    using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["test"].ConnectionString))
    {
        conn.Open();
        SqlCommand cmd = new SqlCommand(@"INSERT INTO Timestamps(timestamp) 
                                            VALUES(@savedTime); 
                                            SELECT SCOPE_IDENTITY() AS id");
        cmd.Parameters.Add(new SqlParameter("savedTime", truncated));
        cmd.Connection = conn;
        var id = cmd.ExecuteScalar();

        SqlCommand get = new SqlCommand(@"SELECT timestamp FROM Timestamps 
                                            WHERE id = @id");

        get.Parameters.Add(new SqlParameter("id", id));
        get.Connection = conn;
        DateTime retrieved = (DateTime)get.ExecuteScalar();

        if (retrieved != truncated)
        {
            Console.WriteLine("original: " + preTruncation.TimeOfDay);
            Console.WriteLine("truncated: " + truncated.TimeOfDay);
            Console.WriteLine("retrieved: " + retrieved.TimeOfDay);
            Console.WriteLine();
        }
    }
}

Obwohl ich erwarte, dass der abgeschnittene Wert entspricht dem Wert, der zurückgegeben wird wieder von der DB, dass ist nicht immer der Fall. Hier einige Beispiel-Ausgabe:

original: 19:59:13.4049965
truncated: 19:59:13.4040000
retrieved: 19:59:13.4030000

original: 19:59:14.4989965
truncated: 19:59:14.4980000
retrieved: 19:59:14.4970000

original: 19:59:15.4749965
truncated: 19:59:15.4740000
retrieved: 19:59:15.4730000

original: 19:59:30.1549965
truncated: 19:59:30.1540000
retrieved: 19:59:30.1530000

TruncateToMilliseconds() sieht wie folgt aus:

public static DateTime TruncateToMilliseconds(this DateTime t)
{
    return new DateTime(t.Year, t.Month, t.Day, t.Hour, t.Minute, t.Second, t.Millisecond);
}

Was gibt? Ist das wirklich unangemessen Rundung, oder bin ich einer falschen Annahme hier?

  • Anscheinend ist der SQL-standard ist die Rundung (nicht abschneiden)... was ist horror, denn es führt zu ungewollten datetimes in die Zukunft. Auch wenn der gleiche server fragt dann "alles, was nicht in der Zukunft", die nur bestimmt und nur eingefügt datetime (die per definition würden wir nicht berücksichtigen, werden in der Zukunft) können ausgeschlossen werden.
InformationsquelleAutor Odrade | 2010-11-29
Schreibe einen Kommentar