Excel VBA字符串,以毫秒计

Excel VBA字符串,以毫秒计,excel,vba,datetime,Excel,Vba,Datetime,我有一个字符串,格式为“yyyy-mm-dd hh:mm:ss.mmm”(其中结尾为毫秒) 我想把它转换成一个数字,最好是一个保存所有信息的日期 我试过CDate(),例如 Dim dateValue As Date dateValue = CDate("2017-12-23 10:29:15.223") 但是获取类型不匹配错误使用Left$函数修剪小数点和毫秒: Dim dateValue As Date dateValue = CDate(Left$("2017-12-23 10:29:1

我有一个字符串,格式为
“yyyy-mm-dd hh:mm:ss.mmm”
(其中结尾为毫秒)

我想把它转换成一个数字,最好是一个保存所有信息的日期

我试过
CDate()
,例如

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

但是获取类型不匹配错误

使用
Left$
函数修剪小数点和毫秒:

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

下面的代码包含管理日期及其毫秒所需的所有组件

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

我不能说我对这个解决方案完全满意,因为打印只隐式地等于日期值。但是,我发现以前有效的日期/时间格式,如“yyyy-mm-dd hh:mm:ss.000”,自2007年以来似乎就不起作用了。但是,应该可以最终证明日期/时间值等于上面包含的格式掩码I对其的呈现。

A
Date
type以1秒的精度保存自1899年12月30日以来的天数。尽管仍然可以通过将日期存储在货币类型中来保存毫秒,因为与日期/双精度相比,它可以多保存4位数字

因此,另一种方法是将日期作为时间戳存储在表示自1899年12月30日以来秒数的
货币类型中:

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
并将时间戳转换回字符串:

Public Function FormatDateEx(dt As Currency) As String
    FormatDateEx = Format(dt / 86400, "yyyy-mm-dd HH:mm:ss") & "." & ((dt - Fix(dt)) * 1000)
End Function

为什么不使用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)
Dim Str作为字符串,MS作为字符串
将日期值设置为日期
作为整数的Dim L
Str=“2017-12-23 10:29:15.223”
对于L=1至Len(Str)
如果左(右(Str,L),1)=“那么
MS=“0”和右(Str,L)
Str=左(Str,Len(Str)-L)
退出
如果结束
下一个L
DateValue=CDate(Str)
如果MS“”,则DateValue=DateAdd(“S”,MS,DateValue)

当小数部分四舍五入时,迈克尔的答案有一个错误(正如吉姆发现的那样)

以下内容更正了错误(在十分之一秒而不是毫秒内进行了轻微修改,并使用了参数化格式模式)


可能重复的可能重复的不幸的是,正如其他答案所强调的那样,
Date
数据类型才是问题所在;它不能将数字保持在毫秒精度。因此
DateAdd
无效,因为日期的小数部分被截断。您可以在
DateAdd
之前和之后使用
debug.print DateValue
进行测试,这是一个很好的解决方案,谢谢Michael。虽然我认为FormatDateEx中有一个小错误。我相信您需要FormatDateEx=Format(*Fix*(dt)/86400,…尝试使用FormatDateEx(CDateEx(“15:59:58.921”))进行测试。如果没有此修复,秒数将变为59秒,而不是58秒(在Excel 2016 64位窗口中)。我尚未对此进行彻底测试,因此请小心。
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