VBA string with milliseconds to date

前端 未结 5 727
无人共我
无人共我 2021-01-19 21:38

I have a string in the form \"yyyy-mm-dd hh:mm:ss.mmm\" (where the end is milliseconds)

I\'d like to convert it to a number, preferably a Date

相关标签:
5条回答
  • 2021-01-19 22:14

    Why not use DateAdd to add the last 0.233 seconds after obtaining the whole second as a date Value?

    Dim Str As String, MS As String
    Dim DateValue As Date
    Dim L as Integer
    Str = "2017-12-23 10:29:15.223"
    For L = 1 to Len(Str)
        If Left(Right(Str, L), 1) = "." Then
            MS = "0" & Right(Str, L)
            Str = Left(Str, Len(Str) - L)
            Exit For
        End If
    Next L
    DateValue = CDate(Str)
    If MS <> "" Then DateValue = DateAdd("S",MS,DateValue)
    
    0 讨论(0)
  • 2021-01-19 22:31

    The code below contains all the components you might need to manage your dates and their milliseconds.

    Private Sub ParseTime()
    
        Dim strTime As String
        Dim Sp() As String
        Dim Dt As Double
    
        strTime = "2017-12-23 10:29:15.221"
        Sp = Split(strTime, ".")
        strTime = Sp(0)
    
        Dt = CDbl(CDate(strTime))
        strTime = "yyyy-mm-dd hh:mm:ss"
        If UBound(Sp) Then
            Dt = Dt + CDbl(Sp(1)) * 1 / 24 / 60 / 60 / (10 ^ Len(Sp(1)))
            strTime = strTime & "." & CInt(Sp(1))
        End If
        Debug.Print Format(Dt, strTime)
    End Sub
    

    I can't say that I am entirely happy with the solution because the print is only implicitly equal to the date value. However, I found that the formerly valid Date/Time format, like "yyyy-mm-dd hh:mm:ss.000", doesn't seem to work since 2007. However, it should be possible to prove conclusively that the Date/Time value is equal to its rendering by the format mask I includedcd above.

    0 讨论(0)
  • 2021-01-19 22:36

    Michael's answer has an error (as spotted by Jim) when the decimal part rounds up.

    The following corrects the error (slightly modified for tenths of seconds rather than milliseconds and with a parameterized format pattern).

    Public Function FormatDateEx(dt As Currency, formatPattern As String) As String
        Rem FormatDateEx = Format(dt / 86400, "yyyy-mm-dd HH:mm:ss") & "." & ((dt - Fix(dt)) * 1000)
        Dim decimalPart As Double
        decimalPart = Round(((dt - Fix(dt)) * 10), 0)
        If (decimalPart = 10) Then
            FormatDateEx = format(dt / 86400, formatPattern) & ".0"
        Else
            FormatDateEx = format(Fix(dt) / 86400, formatPattern) & "." & decimalPart
        End If
    End Function
    
    0 讨论(0)
  • 2021-01-19 22:39

    Use the Left$ function to trim the decimal point and milliseconds:

    Dim dateValue As Date
    dateValue = CDate(Left$("2017-12-23 10:29:15.223", 19))
    
    0 讨论(0)
  • 2021-01-19 22:41

    A Date type holds the number of days since December 30 1899 with a precision of one second. Though it's still possible to hold the milliseconds by storing the date in a currency type since it can hold 4 extra digits compared to a Date/Double.

    So an alternative would be to store the date as a timestamp in a Currency type representing the number of seconds since December 30 1899:

    Public Function CDateEx(text As String) As Currency
        Dim parts() As String
        parts = Split(text, ".")
        CDateEx = CCur(CDate(parts(0)) * 86400) + CCur(parts(1) / 1000)
    End Function
    

    And to convert the timestamp back to a string:

    Public Function FormatDateEx(dt As Currency) As String
        FormatDateEx = Format(dt / 86400, "yyyy-mm-dd HH:mm:ss") & "." & ((dt - Fix(dt)) * 1000)
    End Function
    
    0 讨论(0)
提交回复
热议问题