När ADO trimmar millisekunder från DateTime kolumner
Förord
Om du skapar en SQL Server tabell som innefattar en datetime kolumn, och sedan fyller den med en GetDate() standard och försöker fråga ut den med ADO så kommer du märka att alla data som returneras från datetime kolumnerna inte har med millisekunderna. Om du vill ha med millisekunderna så kan det vara en väldigt irriterande sak att hantera.Hur du hanterar att ADO tar bort millisekunderna från datetimekolumnerna
av Brian Lockwood
Ta det här exemplet från VB:
strSQL = "SELECT DateTime FROM DateTest"
objRs.Open strSQL
? objRs(o)
8/9/2002 11:15:27 PM
Men om du kör SQL-satsen i Query Analyzer så kommer du att få följande resultat:
2002-08-09 23:15:27.490
Första lösningen: Gör det i Transact-SQL
Om du känner till SQL-satsen som du ska köra i VB så kan du manipulera SQL-strängen för att lägga till nödvändig formatering. Det finns tre olika datumformat i SQL Server som du kan använda om du vill hålla kvar millisekunderna:- 9 eller 109 för standard + millisekunder
- 13 eller 113 för europeiskt format
- 21 eller 121 för ODBC format (vilket även matchar ISO formatet)
Ta t ex:
SELECT CONVERT(varchar, DateTime, 21) FROM DateTest
returnerar:
2002-08-09 23:15:27.490
Den här lösningen kanske inte fungerar i alla situationer. Ett annat alternativ är att utföra det i själva Visual Basic.
Andra lösningen: Använd FormatDateTime funktionen
VB erbjuder FormatDateTime funktionen, vilken accepterar VBLongTime konstanten:VBLongTime = visar en tid med hjälp av ett format som är specificerat i datorns regionala inställningar.
Ta t ex:
? FormatDateTime(now(), vbLongTime)
returnerar:
11:41:54 AM
Men än en gång så följer inte millisekunderna med. Jag har försökt med att konfigurera mina regionala inställningar (via kontrollpanelen) för att tillåta millisekunder, men 1) jag stötte på samma problem som ovan, och 2) det skulle skapa ett beroendeskap på din användares desktopkonfigurationer för att ditt program ska kunna fungera, och det är inte bra!
Tredje lösningen: Använd en vanlig VB funktion
Uppenbarligen så är det enda sättet att få detta gjort genom att göra det själva med en vanlig VB funktion som tar med millisekunderna genom en relativt komplicerad algoritm (se längre ner). Resultatet blir rakt på, som du kan se i exemplet:
? FormatDateTimeWithMS(rs(0))
20020809 23:15:27:490
Och här följer koden för den vanliga VB funktionen. Hoppas att du kommer finna den användbar:
Public Function FormatDateTimeWithMS(ByVal dDate As Date, Optional strFormat)
Dim lMilliseconds As Long
Dim bSecondRoundedToUpper As Boolean
lMilliseconds = GetMilliseconds(dDate, bSecondRoundedToUpper)
' om sekunden avrundas uppåt minus en sekund
If bSecondRoundedToUpper Then
dDate = DateAdd("s", -1, dDate)
End If
' kolla om strFormat fattas
If Not IsMissing(strFormat) Then
FormatDateTimeWithMS = Format(dDate, strFormat)
Else
FormatDateTimeWithMS = Format(dDate, "yyyymmdd Hh:Nn:Ss") ' Du kan lägga till ditt eget format
End If
FormatDateTimeWithMS = FormatDateTimeWithMS & ":" & Format(lMilliseconds, "000000")
End Function
Public Function GetMilliseconds(dOriginalDate As Date, ByRef bSecondRoundedToUpper As Boolean) As Long
' hämta strängen (utan millisekunder)
Dim strDateTime As String
strDateTime = CStr(dOriginalDate)
' returnera det till datetime (den här har inte millisekunder)
Dim dRoundedDateTime As Date
dRoundedDateTime = CDate(strDateTime)
' kolla om vi är under noll
If dOriginalDate > 0 Then
' kolla om det avrundade datumet är efter originalet
If dRoundedDateTime > dOriginalDate Then
' subtraherar en sekund
dRoundedDateTime = DateAdd("s", -1, dRoundedDateTime)
' returnerar flag set till on
bSecondRoundedToUpper = True
Else
' returnerar flag set till off
bSecondRoundedToUpper = False
End If
Else
' kolla om det avrundade datumet är före originalet
If dRoundedDateTime < dOriginalDate Then
' lägg till en sekund (genom att subtrahera det! - bugg i VB?)
dRoundedDateTime = DateAdd("s", -1, dRoundedDateTime)
' returnerar flag set till on
bSecondRoundedToUpper = True
Else
' returnerar flag set till off
bSecondRoundedToUpper = False
End If
End If
' millisekunder är antalet ms per dag genom differensen av det avrundade datumet och originaldatumet
GetMilliseconds = 86400000 * Abs(dOriginalDate - dRoundedDateTime)
End Function
' TEST SUB
Public Sub TestMilliseconds
Dim cn As New ADODB.Connection
cn.ConnectionString = "driver={SQL Server};server=(local);uid=sa;pwd=q;database=pubs"
cn.Open
Dim cm As New ADODB.Command
Set cm.ActiveConnection = cn
cm.CommandText = "select getdate(), convert(varchar,getdate(),21)"
cm.CommandType = adCmdText
Dim rs As ADODB.Recordset
Set rs = cm.Execute
Dim strVBFormat As String
strVBFormat = FormatDateTimeWithMS(rs(0).Value)
MsgBox "SERVER FORMAT: " & rs(1).Value & vbCrLf & "VB FORMAT: " & strVBFormat
End Sub
0 Kommentarer