简体   繁体   English

迄今为止的毫秒数 VBA 字符串

[英]VBA string with milliseconds to date

I have a string in the form "yyyy-mm-dd hh:mm:ss.mmm" (where the end is milliseconds)我有一个"yyyy-mm-dd hh:mm:ss.mmm"形式的字符串(结尾是毫秒)

I'd like to convert it to a number, preferably a Date , which preserves all the information我想将它转换为一个数字,最好是一个Date ,它保留了所有信息

I've tried CDate() , eg.我试过CDate() ,例如。

Dim dateValue As Date
dateValue = CDate("2017-12-23 10:29:15.223")

But get a type mismatch error但是得到一个类型不匹配的错误

A Date type holds the number of days since December 30 1899 with a precision of one second. Date类型保存自December 30 1899December 30 1899以来的天数,精度为 1 秒。 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.虽然仍然可以通过将日期存储在货币类型中来保存毫秒,因为与日期/双精度相比,它可以多容纳 4 位数字。

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 :因此,另一种方法是将日期存储为Currency类型的时间戳,表示自December 30 1899December 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

Why not use DateAdd to add the last 0.233 seconds after obtaining the whole second as a date Value?为什么不使用 DateAdd 在获得整秒作为日期值后添加最后 0.233 秒?

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)

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.但是,我发现以前有效的日期/时间格式,如“yyyy-mm-dd hh:mm:ss.000”,自 2007 年以来似乎不再有效。但是,应该可以最终证明日期/Time 值等于我上面包含的格式掩码的渲染。

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

Use the Left$ function to trim the decimal point and milliseconds:使用Left$函数修剪小数点和毫秒:

Dim dateValue As Date
dateValue = CDate(Left$("2017-12-23 10:29:15.223", 19))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM