[AccessD] Losing 3ms on date insert?
Gustav Brock
gustav at cactus.dk
Wed Nov 21 12:14:57 CST 2018
Hi Ryan
That is due to the limited resolution of data type DateTime of SQL Server. Use DateTime2 if you want a precise recording.
I've even created a function to exactly simulate that low resolution given input having a millisecond part (which VBA and Access is able to handle if you are not aware). It's all in the in-line comments:
<code>
' Returns Date1 rounded to the nearest millisecond approximately by 4/5.
' The dividing point for up/down rounding may vary between 0.3 and 0.7ms
' due to the limited resolution of data type Double.
'
' If RoundSqlServer is True, milliseconds are rounded by 3.333ms to match
' the rounding of the Datetime data type of SQL Server - to 0, 3 or 7 as the
' least significant digit:
'
' Msec SqlServer
' 0 0
' 1 0
' 2 3
' 3 3
' 4 3
' 5 7
' 6 7
' 7 7
' 8 7
' 9 10
' 10 10
' 11 10
' 12 13
' 13 13
' 14 13
' 15 17
' 16 17
' 17 17
' 18 17
' 19 20
' ...
' 990 990
' 991 990
' 992 993
' 993 993
' 994 993
' 995 997
' 996 997
' 997 997
' 998 997
' 999 1000
'
' If RoundSqlServer is True and if RoundSecondUp is True, 999ms will be
' rounded up to 1000ms - the next second - which may not be what you wish.
' If RoundSecondUp is False, 999ms will be rounded down to 997ms:
'
' 994 993
' 995 997
' 996 997
' 997 997
' 998 997
' 999 997
'
' If RoundSqlServer is False, RoundSecondUp is ignored.
'
' 2016-09-14. Gustav Brock, Cactus Data ApS, CPH.
'
Public Function DateRoundMillisecond( _
ByVal Date1 As Date, _
Optional RoundSqlServer As Boolean, _
Optional RoundSecondUp As Boolean) _
As Date
Dim Milliseconds As Integer
Dim MsecValue As Date
Dim Result As Date
' Retrieve the millisecond part of Date1.
Milliseconds = Millisecond(Date1)
If RoundSqlServer = True Then
' Perform special rounding to match data type datetime of SQL Server.
Milliseconds = (Milliseconds \ 10) * 10 + Choose(Milliseconds Mod 10 + 1, 0, 0, 3, 3, 3, 7, 7, 7, 7, 10)
If RoundSecondUp = False Then
If Milliseconds = 1000 Then
Milliseconds = 997
End If
End If
End If
' Round Date1 down to the second.
Call RoundOffMilliseconds(Date1)
' Get milliseconds as date value.
MsecValue = MsecSerial(Milliseconds)
' Add milliseconds to rounded date.
Result = DateFromTimespan(DateToTimespan(Date1) + DateToTimespan(MsecValue))
DateRoundMillisecond = Result
End Function
</code>
As you can see, a couple of helper functions are used - their names should indicate their doings. If you are interested, I can post these as well.
/gustav
More information about the AccessD
mailing list