This notation is typical for very large logs and parse it by very slow string functions, like Gustav solution, is not good. More over - it doesn't take into account fractional seconds part AT ALL.
Sub sb_SplitDate()
Dim dDate As Date, dDatDat As Date, dDatTim As Date
Dim i&, lArr&(), lLB&, lUB&
Dim sDatInc$, sArr$(), sClm1$, sClm2$
sDatInc = "1999:12:31:23:59:59:50000000000000000"
sDatInc = "1999:12:31:23:59:59:49999999999999999"
sDatInc = "2016:6:28:10:15:0:49999"
sDatInc = "2016:6:28:10:15:0:50"
sDatInc = "2016:6:28:10:15:0:5"
sDatInc = "2016:6:28:10:15:0:499999999999"
sDatInc = "2016:6:28:10:15:0:999999999999999999999999999"
sDatInc = "2016:6:28:10:15:0:390000000" ' Original
sArr = Split(sDatInc, ":")
lLB = LBound(sArr): lUB = UBound(sArr)
ReDim lArr(lLB To lUB)
For i = lLB To (lUB - 1)
lArr(i) = CLng(sArr(i))
Next
'lArr(6) = CLng(Left$(sArr(6), 1))
lArr(6) = CLng(AscW(sArr(6)) - 48) ' significantly faster
' or AscB
dDatDat = DateSerial(lArr(0), lArr(1), lArr(2))
dDatTim = TimeSerial(lArr(3), lArr(4), lArr(5))
dDate = dDatDat + dDatTim - _
CLng(lArr(6) > 4) / 86400
' standard (school) rounding of the fractional part of seconds
' may gives increasing time, date, month & year ;)
sClm1 = Format$(dDate, "yyyy:mm:dd")
sClm2 = Format$(dDate, "hh:mm:ss")
Debug.Print sDatInc & vbLf & _
sClm1 & " " & sClm2 & _
IIf(lArr(6) > 4, " ' *** Rounded Up!", "") & _
vbLf
Stop
End Sub
.
Re: Gustav
> Normally you round time parts down
Normally I round as task is standing.
If it's a time stamp - Down. If it's a time diapason (how much was ticked?) - Up.
Moreover, even in 1st case it may be rounded Up for special purposes like avoiding near clock zeroes events raising. As task is standing...
> 4/5 rounding will only shift ...
What means "only"? Do you wait any more from rounding above simple shifting of given data to one of boundaries? Any rounding will shift for some value as task was standed by OP: "hh:mm:ss:ms" --> "hh:mm:ss"
> ... shift all the log recordings by 0.5 second
Are you sure? What about given original "2016:6:28:10:15:0:390000000"?
It will be shifted for 0.39-Down or for 0.61-Up...
OP didn't explain which rounding must be applying. But it's not a reason to forget about rounding at all in favor of simple cutting.
I proposed little sophisticated but common solution that easy transformed from one rounding to another. It only needs to add the only '=Chr(39) symbol :)
dDate = dDatDat + dDatTim ' - CLng(lArr(6) > 4) / 86400
It's not difficult, yeah?
But it's a visual representation of one of the this task pitfalls and its solution.
> I believe only one array is needed
- Yeah... I understand. And I'm not surprised, since you believe that string operations are acceptable in such tasks as numbers parsing. The second array is intended exactly to avoid superslow string operations. For myself I would not use Split() at all, but only byte arrays parsing...
And, btw, - does the task was to minimize the quantity of used arrays or to try to cram solution in one-two strings of code?..
Sorry, but the stars are not in favor of strings now :)
.