[AccessD] Access + SQL Server Date/Time Conclusions
Gustav Brock
gustav at cactus.dk
Thu Jul 7 01:41:34 CDT 2022
Hi Paul
I tried to find some math behind the 0, 3, 7 rounding but gave up and fell back to a simple Choose expression in this function, that – if set to round to match DateTime of SQL Server – will return values that always will match exactly:
<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>
/gustav
Fra: Paul Wolstenholme <Paul.W at industrialcontrol.co.nz>
Sendt: 6. juli 2022 23:10
Til: Access Developers discussion and problem solving <accessd at databaseadvisors.com>
Cc: Gustav Brock <gustav at cactus.dk>
Emne: Re: [AccessD] Access + SQL Server Date/Time Conclusions
Gustav,
I had not considered compatibility with older drivers. Thanks for pointing that out.
The concept of non-uniform resolution and the measurements that best describe it was missing from my education. My attempts to resolve this matter by looking for precise definitions of resolution in this context were totally thwarted by resolution being such an overused word. About 3.333 ms and up to 4 ms and 3 or 4 ms are probably all correct. I lack the resolve to look further.
Paul Wolstenholme
On Wed, 6 Jul 2022 at 19:57, Gustav Brock via AccessD <accessd at databaseadvisors.com<mailto:accessd at databaseadvisors.com>> wrote:
Hi Paul
I didn’t write 3.333 ms, I wrote about 3.333 ms as the exact value varies and isn’t that important; actually, it is the average.
DateTime is preferred among most Access developers, because it will cause zero troubles and requires no concerns. It even works with the native ”SQL Server” ODBC driver of Windows, should you be forced to work with that in some locked down corporate environment.
Also, if you don’t operate with early dates and millisecond precision, DateTime2 offers nothing extra.
/gustav
More information about the AccessD
mailing list