By Frank Kalis
Da sitzt man abends völlig entspannt am Schreibtisch, blättert in alten Unterlagen aus der Studienzeit weil man sich an gewisse mathematische Zusammenhänge nicht mehr so direkt aus dem Kopf erinnern kann, und - zack - stolpert man über Integer Arithmetik. Die (durchaus verworrene) Assoziationskette zu SQL Server und DATETIMEs führt jedenfalls dann dazu, daß das Mathebuch erst einmal Mathebuch ist und bleibt und wir einen Selbstversuch in Datumsarithmetik unternehmen.
DECLARE @dt DATETIME DECLARE @TageSeit19000101 INTEGER DECLARE @ClockTicks INTEGER SET @dt = GETDATE() SET @TageSeit19000101 = CAST( SUBSTRING(CAST(@dt AS BINARY(8)),1,4) AS INT) SET @ClockTicks = CAST(SUBSTRING(CAST(@dt AS BINARY(8)),5,4) AS INT) SELECT @dt AS JetztGerade , @TageSeit19000101 AS AnzTage , CAST(@TageSeit19000101 AS DATETIME) HeuteOhneZeit , @ClockTicks AS CT , @ClockTicks / (300 * 60 * 60) AS Stunden , (@ClockTicks % (300 * 60 * 60)) / (300 * 60) AS Minuten , ((@ClockTicks % (300 * 60 * 60)) % (300 * 60)) / (300) AS Sekunden , CAST(ROUND(((((@ClockTicks % (300 * 60 * 60)) % (300 * 60)) % (300)) / 3.0) * 10,0) AS INT) AS MS JetztGerade AnzTage HeuteOhneZeit CT Stunden Minuten Sekunden MS ------------------------ ------- ------------------------ --------- ------- ------- -------- ---- 2005-08-02 21:20:13.300 38564 2005-08-02 00:00:00.000 23043990 21 20 13 300 (1 row(s) affected)
Man kann hier auch schön nachweisen, daß die zweiten 4 Bytes eines DATETIMEs tatsächlich nicht die Millisekunden seit Mitternacht, wie in BOL beschrieben, sondern vielmehr die Clockticks seit Mitternacht speichert.
SELECT ((300 % (300 * 60 * 60)) % (300 * 60)) / (300) AS DatetimeSpeichertClockTicks DatetimeSpeichertClockTicks --------------------------- 1 (1 row(s) affected)
Die obige Rechnung mit 300 anstelle der Variablen @ClockTicks gibt eine 1 als Anzahl der Sekunden seit Mitternacht aus. Würden tatsächlich Millisekunden gespeichert, hätte eine 0 erscheinen müssen. Man vergleiche dazu auch diesen Beitrag. So, zurück zum Mathematikbuch. :-)